2 # Copyright (C) 2006, 2007 Shawn Pearce
10 field browser_status
{Starting...
}
11 field browser_stack
{}
14 field ls_buf
{}; # Buffered record output from ls-tree
16 constructor new
{commit
{path
{}}} {
19 wm title
$top "[appname] ([reponame]): File Browser"
21 set browser_commit
$commit
22 set browser_path
$browser_commit:$path
25 -textvariable @browser_path
\
31 pack $w.path
-anchor w
-side top
-fill x
35 text $w_list -background white
-borderwidth 0 \
41 -xscrollcommand [list $w.
list.sbx
set] \
42 -yscrollcommand [list $w.
list.sby
set]
43 $w_list tag conf in_sel
\
44 -background [$w_list cget
-foreground] \
45 -foreground [$w_list cget
-background]
46 scrollbar $w.
list.sbx
-orient h
-command [list $w_list xview
]
47 scrollbar $w.
list.sby
-orient v
-command [list $w_list yview
]
48 pack $w.
list.sbx
-side bottom
-fill x
49 pack $w.
list.sby
-side right
-fill y
50 pack $w_list -side left
-fill both
-expand 1
51 pack $w.
list -side top
-fill both
-expand 1
54 -textvariable @browser_status
\
59 pack $w.status
-anchor w
-side bottom
-fill x
61 bind $w_list <Button-1
> "[cb _click 0 @%x,%y];break"
62 bind $w_list <Double-Button-1
> "[cb _click 1 @%x,%y];break"
63 bind $w_list <$M1B-Up
> "[cb _parent] ;break"
64 bind $w_list <$M1B-Left
> "[cb _parent] ;break"
65 bind $w_list <Up
> "[cb _move -1] ;break"
66 bind $w_list <Down
> "[cb _move 1] ;break"
67 bind $w_list <$M1B-Right
> "[cb _enter] ;break"
68 bind $w_list <Return
> "[cb _enter] ;break"
69 bind $w_list <Prior
> "[cb _page -1] ;break"
70 bind $w_list <Next
> "[cb _page 1] ;break"
71 bind $w_list <Left
> break
72 bind $w_list <Right
> break
74 bind $w_list <Visibility
> [list focus $w_list]
77 _ls
$this $browser_commit:$path $path
79 _ls
$this $browser_commit $path
85 if {$browser_busy} return
86 set lno
[lindex [split [$w index in_sel.first
] .
] 0]
88 if {[lindex $browser_files [expr {$lno - 1}]] ne
{}} {
89 $w tag remove in_sel
0.0 end
90 $w tag add in_sel
$lno.0 [expr {$lno + 1}].0
96 if {$browser_busy} return
97 $w yview scroll
$dir pages
100 * [llength $browser_files]
102 if {[lindex $browser_files [expr {$lno - 1}]] ne
{}} {
103 $w tag remove in_sel
0.0 end
104 $w tag add in_sel
$lno.0 [expr {$lno + 1}].0
110 if {$browser_busy} return
111 set info [lindex $browser_files 0]
112 if {[lindex $info 0] eq
{parent
}} {
113 set parent
[lindex $browser_stack end-1
]
114 set browser_stack
[lrange $browser_stack 0 end-2
]
115 if {$browser_stack eq
{}} {
116 regsub {:.
*$} $browser_path {:} browser_path
118 regsub {/[^
/]+$} $browser_path {} browser_path
120 set browser_status
"Loading $browser_path..."
121 _ls
$this [lindex $parent 0] [lindex $parent 1]
126 if {$browser_busy} return
127 set lno
[lindex [split [$w index in_sel.first
] .
] 0]
128 set info [lindex $browser_files [expr {$lno - 1}]]
130 switch -- [lindex $info 0] {
135 set name
[lindex $info 2]
136 set escn
[escape_path
$name]
137 set browser_status
"Loading $escn..."
138 append browser_path
$escn
139 _ls
$this [lindex $info 1] $name
142 set name
[lindex $info 2]
144 foreach n
$browser_stack {
145 append p
[lindex $n 1]
148 blame
::new $browser_commit $p
154 method _click
{was_double_click pos
} {
155 if {$browser_busy} return
156 set lno
[lindex [split [$w index
$pos] .
] 0]
159 if {[lindex $browser_files [expr {$lno - 1}]] ne
{}} {
160 $w tag remove in_sel
0.0 end
161 $w tag add in_sel
$lno.0 [expr {$lno + 1}].0
162 if {$was_double_click} {
168 method _ls
{tree_id
{name
{}}} {
173 $w conf
-state normal
174 $w tag remove in_sel
0.0 end
176 if {$browser_stack ne
{}} {
177 $w image create end
\
178 -align center
-padx 5 -pady 1 \
181 $w insert end
{[Up To Parent
]}
182 lappend browser_files parent
184 lappend browser_stack
[list $tree_id $name]
185 $w conf
-state disabled
187 set fd
[git_read ls-tree
-z $tree_id]
188 fconfigure $fd -blocking 0 -translation binary -encoding binary
189 fileevent $fd readable
[cb _read
$fd]
193 append ls_buf
[read $fd]
194 set pck
[split $ls_buf "\0"]
195 set ls_buf
[lindex $pck end
]
197 set n
[llength $browser_files]
198 $w conf
-state normal
199 foreach p
[lrange $pck 0 end-1
] {
200 set tab
[string first
"\t" $p]
201 if {$tab == -1} continue
203 set info [split [string range
$p 0 [expr {$tab - 1}]] { }]
204 set path
[string range
$p [expr {$tab + 1}] end
]
205 set type
[lindex $info 1]
206 set object
[lindex $info 2]
217 set image file_question
221 if {$n > 0} {$w insert end
"\n"}
222 $w image create end
\
223 -align center
-padx 5 -pady 1 \
226 $w insert end
[escape_path
$path]
227 lappend browser_files
[list $type $object $path]
229 $w conf
-state disabled
233 set browser_status Ready.
237 $w tag add in_sel
1.0 2.0
249 field w
; # widget path
250 field w_rev
; # mega-widget to pick the initial revision
252 constructor dialog
{} {
254 wm title
$top "[appname] ([reponame]): Browse Branch Files"
256 wm geometry
$top "+[winfo rootx .]+[winfo rooty .]"
260 -text {Browse Branch Files
} \
262 pack $w.header
-side top
-fill x
265 button $w.buttons.browse
-text Browse
\
268 pack $w.buttons.browse
-side right
269 button $w.buttons.cancel
-text {Cancel
} \
270 -command [list destroy $w]
271 pack $w.buttons.cancel
-side right
-padx 5
272 pack $w.buttons
-side bottom
-fill x
-pady 10 -padx 10
274 set w_rev
[::choose_rev::new $w.rev
{Revision
}]
275 $w_rev bind_listbox
<Double-Button-1
> [cb _open
]
276 pack $w.rev
-anchor nw
-fill both
-expand 1 -pady 5 -padx 5
278 bind $w <Visibility
> [cb _visible
]
279 bind $w <Key-Escape
> [list destroy $w]
280 bind $w <Key-Return
> [cb _open
]\;break
285 if {[catch {$w_rev commit_or_die
} err
]} {
288 set name
[$w_rev get
]