+ set phase {}
+ if {$redisplaying} {
+ if {$stopped == 0 && [info exists selectedline]} {
+ selectline $selectedline
+ }
+ if {$stopped == 1} {
+ set stopped 0
+ after idle drawgraph
+ } else {
+ set redisplaying 0
+ }
+ }
+}
+
+proc dofind {} {
+ global findtype findloc findstring markedmatches commitinfo
+ global numcommits lineid linehtag linentag linedtag
+ global mainfont namefont canv canv2 canv3 selectedline
+ global matchinglines
+ unmarkmatches
+ set matchinglines {}
+ set fldtypes {Headline Author Date Committer CDate Comment}
+ if {$findtype == "IgnCase"} {
+ set fstr [string tolower $findstring]
+ } else {
+ set fstr $findstring
+ }
+ set mlen [string length $findstring]
+ if {$mlen == 0} return
+ if {![info exists selectedline]} {
+ set oldsel -1
+ } else {
+ set oldsel $selectedline
+ }
+ set didsel 0
+ for {set l 0} {$l < $numcommits} {incr l} {
+ set id $lineid($l)
+ set info $commitinfo($id)
+ set doesmatch 0
+ foreach f $info ty $fldtypes {
+ if {$findloc != "All fields" && $findloc != $ty} {
+ continue
+ }
+ if {$findtype == "Regexp"} {
+ set matches [regexp -indices -all -inline $fstr $f]
+ } else {
+ if {$findtype == "IgnCase"} {
+ set str [string tolower $f]
+ } else {
+ set str $f
+ }
+ set matches {}
+ set i 0
+ while {[set j [string first $fstr $str $i]] >= 0} {
+ lappend matches [list $j [expr $j+$mlen-1]]
+ set i [expr $j + $mlen]
+ }
+ }
+ if {$matches == {}} continue
+ set doesmatch 1
+ if {$ty == "Headline"} {
+ markmatches $canv $l $f $linehtag($l) $matches $mainfont
+ } elseif {$ty == "Author"} {
+ markmatches $canv2 $l $f $linentag($l) $matches $namefont
+ } elseif {$ty == "Date"} {
+ markmatches $canv3 $l $f $linedtag($l) $matches $mainfont
+ }
+ }
+ if {$doesmatch} {
+ lappend matchinglines $l
+ if {!$didsel && $l > $oldsel} {
+ selectline $l
+ set didsel 1
+ }
+ }
+ }
+ if {$matchinglines == {}} {
+ bell
+ } elseif {!$didsel} {
+ selectline [lindex $matchinglines 0]
+ }
+}
+
+proc findnext {} {
+ global matchinglines selectedline
+ if {![info exists matchinglines]} {
+ dofind
+ return
+ }
+ if {![info exists selectedline]} return
+ foreach l $matchinglines {
+ if {$l > $selectedline} {
+ selectline $l
+ return
+ }
+ }
+ bell
+}
+
+proc findprev {} {
+ global matchinglines selectedline
+ if {![info exists matchinglines]} {
+ dofind
+ return
+ }
+ if {![info exists selectedline]} return
+ set prev {}
+ foreach l $matchinglines {
+ if {$l >= $selectedline} break
+ set prev $l
+ }
+ if {$prev != {}} {
+ selectline $prev
+ } else {
+ bell
+ }
+}
+
+proc markmatches {canv l str tag matches font} {
+ set bbox [$canv bbox $tag]
+ set x0 [lindex $bbox 0]
+ set y0 [lindex $bbox 1]
+ set y1 [lindex $bbox 3]
+ foreach match $matches {
+ set start [lindex $match 0]
+ set end [lindex $match 1]
+ if {$start > $end} continue
+ set xoff [font measure $font [string range $str 0 [expr $start-1]]]
+ set xlen [font measure $font [string range $str 0 [expr $end]]]
+ set t [$canv create rect [expr $x0+$xoff] $y0 [expr $x0+$xlen+2] $y1 \
+ -outline {} -tags matches -fill yellow]
+ $canv lower $t
+ }
+}
+
+proc unmarkmatches {} {
+ global matchinglines
+ allcanvs delete matches
+ catch {unset matchinglines}