Eskil

Diff
Login

Differences From Artifact [ba55165e23]:

To Artifact [c41ba3ab7e]:


50
51
52
53
54
55
56
57
58
59
60
61
62
63

64
65
66
67
68
69
70
#-----------------------------------------------
# $Revision$
#-----------------------------------------------
# the next line restarts using wish \
exec wish "$0" "$@"

set debug 1
set diffver "Version 1.9.4b  2002-04-24"
set tmpcnt 0
set tmpfiles {}
set thisscript [file join [pwd] [info script]]
set thisdir [file dirname $thisscript]
set ::diff(cvsExists) [expr {![string equal [auto_execok cvs] ""]}]
set ::diff(diffexe) diff


if {[info exists env(TEMP)]} {
    set ::diff(tmpdir) $env(TEMP)
} elseif {[info exists env(TMP)]} {
    set ::diff(tmpdir) $env(TMP)
} else {
    if {$tcl_platform(platform) == "windows"} {







|






>







50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#-----------------------------------------------
# $Revision$
#-----------------------------------------------
# the next line restarts using wish \
exec wish "$0" "$@"

set debug 1
set diffver "Version 1.9.4b  2002-05-14"
set tmpcnt 0
set tmpfiles {}
set thisscript [file join [pwd] [info script]]
set thisdir [file dirname $thisscript]
set ::diff(cvsExists) [expr {![string equal [auto_execok cvs] ""]}]
set ::diff(diffexe) diff
set ::diff(diffutil) [expr {![catch {package require DiffUtil}]}]

if {[info exists env(TEMP)]} {
    set ::diff(tmpdir) $env(TEMP)
} elseif {[info exists env(TMP)]} {
    set ::diff(tmpdir) $env(TMP)
} else {
    if {$tcl_platform(platform) == "windows"} {
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
        auto_reset
        set ::diff(cvsExists) [expr {![string equal [auto_execok cvs] ""]}]
    }
}

proc cleanupAndExit {} {
    if {$::diff(diffexe) != "diff"} {
        file delete $::diff(diffexe)
    }
    cleartmp
    exit
}

# Format a line number
proc myforml {lineNo} {







|







95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
        auto_reset
        set ::diff(cvsExists) [expr {![string equal [auto_execok cvs] ""]}]
    }
}

proc cleanupAndExit {} {
    if {$::diff(diffexe) != "diff"} {
        catch {file delete $::diff(diffexe)}
    }
    cleartmp
    exit
}

# Format a line number
proc myforml {lineNo} {
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
    set name [file join $::diff(tmpdir) "tmpd[pid]a$::tmpcnt"]
    lappend ::tmpfiles $name
    return $name
}

proc cleartmp {} {
    foreach f $::tmpfiles {
        file delete $f
    }
    set ::tmpfiles {}
}

# 2nd stage line parsing
# Recursively look for common substrings in strings s1 and s2
##syntax compareMidString x x n n x?







|







120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
    set name [file join $::diff(tmpdir) "tmpd[pid]a$::tmpcnt"]
    lappend ::tmpfiles $name
    return $name
}

proc cleartmp {} {
    foreach f $::tmpfiles {
        catch {file delete $f}
    }
    set ::tmpfiles {}
}

# 2nd stage line parsing
# Recursively look for common substrings in strings s1 and s2
##syntax compareMidString x x n n x?
235
236
237
238
239
240
241










242
243
244
245
246
247
248
        compareMidString $left1 $left2 left1 left2 $test
        compareMidString $right1 $right2 right1 right2 $test

        set res1 [concat $left1 [list $mid1] $right1]
        set res2 [concat $left2 [list $mid2] $right2]
    }
}











# Compare two lines to find inequalities to highlight.
# The return value is, for each line, a list where the first, third etc.
# element is equal between the lines. The second, fourth etc. will be
# highlighted.
##syntax compareLines x x n n x?
proc compareLines {line1 line2 res1Name res2Name {test 0}} {







>
>
>
>
>
>
>
>
>
>







236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
        compareMidString $left1 $left2 left1 left2 $test
        compareMidString $right1 $right2 right1 right2 $test

        set res1 [concat $left1 [list $mid1] $right1]
        set res2 [concat $left2 [list $mid2] $right2]
    }
}

proc compareLinesX {line1 line2 res1Name res2Name {test 0}} {
    global Pref
    upvar $res1Name res1
    upvar $res2Name res2

    set args "$Pref(ignore)\
            [expr {($Pref(lineparsewords) && !$test) ? "-word" : ""}]"
    eval DiffUtil::compareLines $args \$line1 \$line2 res1 res2
}

# Compare two lines to find inequalities to highlight.
# The return value is, for each line, a list where the first, third etc.
# element is equal between the lines. The second, fourth etc. will be
# highlighted.
##syntax compareLines x x n n x?
proc compareLines {line1 line2 res1Name res2Name {test 0}} {
330
331
332
333
334
335
336
337
338

339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360

361
362
363
364
365
366
367
368





369

370
371
372
373
374
375
376
            }
            set t1 $s1
            set t2 $s2
        }
    }

    # Make the result
    if {$leftp1 > $t1} {
        set res1 [list $line1]

    } else {
        set right1 [string range $line1 [expr {$t1 + 1}] end]
        set mid1 [string range $line1 $leftp1 $t1]
        set left1 [string range $line1 0 [expr {$leftp1 - 1}]]
        set res1 [list $left1 $mid1 $right1]
    }
    if {$leftp2 > $t2} {
        set res2 [list $line2]
    } else {
        set right2 [string range $line2 [expr {$t2 + 1}] end]
        set mid2 [string range $line2 $leftp2 $t2]
        set left2 [string range $line2 0 [expr {$leftp2 - 1}]]
        set res2 [list $left2 $mid2 $right2]
    }
    if {$Pref(extralineparse) != 0 && $leftp1 <= $t1 && $leftp2 <= $t2} {
        compareMidString $mid1 $mid2 mid1 mid2 $test
        # Replace middle element in res* with list elements from mid*
        #set res1 [eval lreplace \$res1 1 1 $mid1]
        #set res2 [eval lreplace \$res2 1 1 $mid2]
        # This makes use of pure-list optimisation in eval
        set res1 [eval [linsert $mid1 0 lreplace $res1 1 1]]
        set res2 [eval [linsert $mid2 0 lreplace $res2 1 1]]

    }
}

# Compare two lines and rate how much they resemble each other.
# This has never worked well. Some day I'll sit down, think this through,
# and come up with a better algorithm.
proc compareLines2 {line1 line2} {
    compareLines $line1 $line2 res1 res2 1







    # Collect identical pieces and different pieces
    set sames {}
    set diffs1 {}
    set diffs2 {}
    foreach {same diff} $res1 {
        lappend sames $same
        if {$diff != ""} {







|

>





|
<
<
<




|
|
|
|
|
|
|
|
|
>








>
>
>
>
>
|
>







341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356



357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
            }
            set t1 $s1
            set t2 $s2
        }
    }

    # Make the result
    if {$leftp1 > $t1 && $leftp2 > $t2} {
        set res1 [list $line1]
        set res2 [list $line2]
    } else {
        set right1 [string range $line1 [expr {$t1 + 1}] end]
        set mid1 [string range $line1 $leftp1 $t1]
        set left1 [string range $line1 0 [expr {$leftp1 - 1}]]
        set res1 [list $left1 $mid1 $right1]




        set right2 [string range $line2 [expr {$t2 + 1}] end]
        set mid2 [string range $line2 $leftp2 $t2]
        set left2 [string range $line2 0 [expr {$leftp2 - 1}]]
        set res2 [list $left2 $mid2 $right2]

        if {$Pref(extralineparse) != 0 && $mid1 != "" && $mid2 != ""} {
            compareMidString $mid1 $mid2 mid1 mid2 $test
            # Replace middle element in res* with list elements from mid*
            #set res1 [eval lreplace \$res1 1 1 $mid1]
            #set res2 [eval lreplace \$res2 1 1 $mid2]
            # This makes use of pure-list optimisation in eval
            set res1 [eval [linsert $mid1 0 lreplace $res1 1 1]]
            set res2 [eval [linsert $mid2 0 lreplace $res2 1 1]]
        }
    }
}

# Compare two lines and rate how much they resemble each other.
# This has never worked well. Some day I'll sit down, think this through,
# and come up with a better algorithm.
proc compareLines2 {line1 line2} {
    compareLines $line1 $line2 res1 res2 1
    if {$::diff(diffutil)} {
        compareLinesX $line1 $line2 xres1 xres2 1
        if {$res1 != $xres1 || $res2 != $xres2} {
            tk_messageBox -title "Rate Mismatch!" \
                    -message ":$res1:\n:$res2:\n:$xres1:\n:$xres2:"
        }
    }
    # Collect identical pieces and different pieces
    set sames {}
    set diffs1 {}
    set diffs2 {}
    foreach {same diff} $res1 {
        lappend sames $same
        if {$diff != ""} {
631
632
633
634
635
636
637







638
639
640
641
642
643
644
# Insert one line in each text widget.
# Mark them as changed, and optionally parse them.
proc insertMatchingLines {line1 line2} {
    global doingLine1 doingLine2 Pref

    if {$Pref(parse) != 0} {
        compareLines $line1 $line2 res1 res2







        set dotag 0
        set n [maxabs [llength $res1] [llength $res2]]
        .ft1.tl insert end [myforml $doingLine1] "hl$::HighLightCount change"
        .ft2.tl insert end [myforml $doingLine2] "hl$::HighLightCount change"
        set new1 new1
        set new2 new2
        set change change







>
>
>
>
>
>
>







647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
# Insert one line in each text widget.
# Mark them as changed, and optionally parse them.
proc insertMatchingLines {line1 line2} {
    global doingLine1 doingLine2 Pref

    if {$Pref(parse) != 0} {
        compareLines $line1 $line2 res1 res2
        if {$::diff(diffutil)} {
            compareLinesX $line1 $line2 xres1 xres2
            if {$res1 != $xres1 || $res2 != $xres2} {
                tk_messageBox -title Mismatch! \
                        -message ":$res1:\n:$res2:\n:$xres1:\n:$xres2:"
            }
        }
        set dotag 0
        set n [maxabs [llength $res1] [llength $res2]]
        .ft1.tl insert end [myforml $doingLine1] "hl$::HighLightCount change"
        .ft2.tl insert end [myforml $doingLine2] "hl$::HighLightCount change"
        set new1 new1
        set new2 new2
        set change change
804
805
806
807
808
809
810



811
812
813
814
815
816
817
818
819
820

821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836

837
838
839
840
841
842
843
        .ft1.tl insert end "\n"
        .ft2.tl insert end "\n"
    }

    # Process the block

    if {$n1 == $n2 && ($n1 == 1 || $Pref(parse) < 2)} {



        for {set t 0} {$t < $n1} {incr t} {
            gets $ch1 textline1
            gets $ch2 textline2
            insertMatchingLines $textline1 $textline2
        }
        lappend changesList $mapMax $n1 change $line1 $n1 $line2 $n2
        incr mapMax $n1
    } else {
        if {$n1 != 0 && $n2 != 0 && $Pref(parse) >= 2 && \
                ($n1 * $n2 < 1000 || $Pref(parse) == 3)} {

            set block1 {}
            for {set t 0} {$t < $n1} {incr t} {
                gets $ch1 apa
                lappend block1 $apa
            }
            set block2 {}
            for {set t 0} {$t < $n2} {incr t} {
                gets $ch2 apa
                lappend block2 $apa
            }
            set apa [insertMatchingBlocks $block1 $block2]

            lappend changesList $mapMax $apa change \
                    $line1 $n1 $line2 $n2
            incr mapMax $apa
        } else {

            for {set t 0} {$t < $n1} {incr t} {
                gets $ch1 apa
                insert 1 $doingLine1 $apa $tag1
                incr doingLine1
            }
            for {set t 0} {$t < $n2} {incr t} {
                gets $ch2 apa







>
>
>










>
















>







827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
        .ft1.tl insert end "\n"
        .ft2.tl insert end "\n"
    }

    # Process the block

    if {$n1 == $n2 && ($n1 == 1 || $Pref(parse) < 2)} {
        # Never do block parsing for one line blocks.
        # If block parsing is turned off, only do line parsing for
        # blocks of equal size.
        for {set t 0} {$t < $n1} {incr t} {
            gets $ch1 textline1
            gets $ch2 textline2
            insertMatchingLines $textline1 $textline2
        }
        lappend changesList $mapMax $n1 change $line1 $n1 $line2 $n2
        incr mapMax $n1
    } else {
        if {$n1 != 0 && $n2 != 0 && $Pref(parse) >= 2 && \
                ($n1 * $n2 < 1000 || $Pref(parse) == 3)} {
            # Full block parsing
            set block1 {}
            for {set t 0} {$t < $n1} {incr t} {
                gets $ch1 apa
                lappend block1 $apa
            }
            set block2 {}
            for {set t 0} {$t < $n2} {incr t} {
                gets $ch2 apa
                lappend block2 $apa
            }
            set apa [insertMatchingBlocks $block1 $block2]

            lappend changesList $mapMax $apa change \
                    $line1 $n1 $line2 $n2
            incr mapMax $apa
        } else {
            # No extra parsing at all.
            for {set t 0} {$t < $n1} {incr t} {
                gets $ch1 apa
                insert 1 $doingLine1 $apa $tag1
                incr doingLine1
            }
            for {set t 0} {$t < $n2} {incr t} {
                gets $ch2 apa
953
954
955
956
957
958
959

960
961
962
963
964
965
966
    global diff Pref

    cleartmp
    set diff(rightFile) $diff(conflictFile)
    set diff(leftFile) $diff(conflictFile)
}


proc displayOnePatch {leftLines rightLines leftLine rightLine} {
    emptyline 1
    emptyline 2

    set leftlen [llength $leftLines]
    set rightlen [llength $rightLines]








>







981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
    global diff Pref

    cleartmp
    set diff(rightFile) $diff(conflictFile)
    set diff(leftFile) $diff(conflictFile)
}

# Display one chunk from a patch file
proc displayOnePatch {leftLines rightLines leftLine rightLine} {
    emptyline 1
    emptyline 2

    set leftlen [llength $leftLines]
    set rightlen [llength $rightLines]

1308
1309
1310
1311
1312
1313
1314

1315
1316
1317
1318
1319
1320
1321
1322
1323


1324
1325
1326
1327
1328
1329
1330
        return
    } else {
        enableRedo
    }

    busyCursor


    foreach w {.ft1.tl .ft1.tt .ft2.tl .ft2.tt} {
        $w configure -state normal
        $w delete 1.0 end
    }
    set changesList {}
    set mapMax 0
    set ::HighLightCount 0
    highLightChange -1
    drawMap -1


    set ::diff(eqLabel) "*"

    update idletasks

    if {$diff(mode) == "patch"} {
        displayPatch
        drawMap -1







>









>
>







1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
        return
    } else {
        enableRedo
    }

    busyCursor

    # Clear up everything before starting processing
    foreach w {.ft1.tl .ft1.tt .ft2.tl .ft2.tt} {
        $w configure -state normal
        $w delete 1.0 end
    }
    set changesList {}
    set mapMax 0
    set ::HighLightCount 0
    highLightChange -1
    drawMap -1
    # Display a star during diff execution, to know when the internal
    # processing starts, and when the label is "valid".
    set ::diff(eqLabel) "*"

    update idletasks

    if {$diff(mode) == "patch"} {
        displayPatch
        drawMap -1
1338
1339
1340
1341
1342
1343
1344




1345

1346

1347
1348
1349
1350
1351
1352
1353
    } elseif {$diff(mode) == "RCS" || $diff(mode) == "CVS"} {
        prepareRCS
    } elseif {[string match "conflict*" $diff(mode)]} {
        prepareConflict
    }

    # Run diff and parse the result.




    set differr [catch {eval exec \$::diff(diffexe) $Pref(dopt) $Pref(ignore) \

            \$diff(leftFile) \$diff(rightFile)} diffres]


    set apa [split $diffres "\n"]
    set result {}
    foreach i $apa {
        if {[string match {[0-9]*} $i]} {
            lappend result $i
        }







>
>
>
>
|
>
|
>







1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
    } elseif {$diff(mode) == "RCS" || $diff(mode) == "CVS"} {
        prepareRCS
    } elseif {[string match "conflict*" $diff(mode)]} {
        prepareConflict
    }

    # Run diff and parse the result.
    if {$::diff(diffutil)} {
        set differr [catch {eval DiffUtil::diffFiles $Pref(ignore) \
                \$diff(leftFile) \$diff(rightFile)} diffres]
    } else {
        set differr [catch {eval exec \$::diff(diffexe) \
                $Pref(dopt) $Pref(ignore) \
                \$diff(leftFile) \$diff(rightFile)} diffres]
    }

    set apa [split $diffres "\n"]
    set result {}
    foreach i $apa {
        if {[string match {[0-9]*} $i]} {
            lappend result $i
        }
1367
1368
1369
1370
1371
1372
1373

1374
1375
1376
1377
1378
1379
1380
            return
        } else {
            set ::diff(eqLabel) "="
        }
    } else {
        set ::diff(eqLabel) " "
    }

    update idletasks

    set ch1 [open $diff(leftFile)]
    set ch2 [open $diff(rightFile)]
    if {$::tcl_platform(platform) == "windows" && $Pref(crlf)} {
        fconfigure $ch1 -translation crlf
        fconfigure $ch2 -translation crlf







>







1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
            return
        } else {
            set ::diff(eqLabel) "="
        }
    } else {
        set ::diff(eqLabel) " "
    }
    # Update the equal label immediately for better feedback
    update idletasks

    set ch1 [open $diff(leftFile)]
    set ch2 [open $diff(rightFile)]
    if {$::tcl_platform(platform) == "windows" && $Pref(crlf)} {
        fconfigure $ch1 -translation crlf
        fconfigure $ch2 -translation crlf
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
    set max 0.0
    foreach w {.ft1.tl .ft1.tt .ft2.tl .ft2.tt} {
        if {[$w index end] > $max} {
            set max [$w index end]
        }
    }
    foreach w {.ft1.tl .ft1.tt .ft2.tl .ft2.tt} {
        set d [expr {int($max - [$w index end])}]
        for {set t 0} {$t < $d} {incr t} {
            $w insert end \n
        }
    }

    close $ch1
    close $ch2







|







1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
    set max 0.0
    foreach w {.ft1.tl .ft1.tt .ft2.tl .ft2.tt} {
        if {[$w index end] > $max} {
            set max [$w index end]
        }
    }
    foreach w {.ft1.tl .ft1.tt .ft2.tl .ft2.tt} {
        set d [expr {int($max) - int([$w index end])}]
        for {set t 0} {$t < $d} {incr t} {
            $w insert end \n
        }
    }

    close $ch1
    close $ch2
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966






1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986












1987

1988



1989


1990



1991




1992














1993
1994
1995
1996
1997
1998
1999
2000

2001
2002

2003
2004
2005
2006
2007

2008

2009
2010
2011
2012
2013
2014

2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025

2026

2027
2028
2029
2030
2031
2032
2033
2034

2035

2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055

2056

2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087












































2088








2089





2090


2091


2092








2093




2094
2095









2096



2097



2098


2099




2100







2101



2102







2103

2104







2105




2106

2107

















2108
2109






2110

2111







2112




2113





2114






2115

2116








2117









2118
2119
2120
2121
2122
2123
2124
    radiobutton $w.f.rb4 -text "RL" -value 21 -variable curMergeSel \
            -command selectMerge
    bind $w <Key-Left>  {focus .merge ; set curMergeSel 1 ; selectMerge}
    bind $w <Key-Right> {focus .merge ; set curMergeSel 2 ; selectMerge}

    button $w.f.bl -text "All L" -command {selectMergeAll 1}
    button $w.f.br -text "All R" -command {selectMergeAll 2}
    checkbutton $w.f.bm -text "Pure" -variable diff(mode) \
            -onvalue "conflictPure" -offvalue "conflict" -command {doDiff}

    button $w.f.b1 -text "Prev" -command {nextMerge -1}
    button $w.f.b2 -text "Next" -command {nextMerge 1}
    bind $w <Key-Down> {focus .merge ; nextMerge 1}
    bind $w <Key-Up>   {focus .merge ; nextMerge -1}

    button $w.f.bs -text "Save" -command saveMerge
    button $w.f.bq -text "Close" -command closeMerge
    wm protocol $w WM_CLOSE_WINDOW closeMerge

    grid $w.f.rb1 $w.f.rb2 $w.f.rb3 $w.f.rb4 x $w.f.b1 $w.f.b2 x \
            $w.f.bl $w.f.br x $w.f.bm x $w.f.bs $w.f.bq
    grid columnconfigure $w.f {4 7 10 12} -minsize 10
    grid columnconfigure $w.f 10 -weight 1







    text $w.t -width 80 -height 20 -xscrollcommand "$w.sbx set" \
            -yscrollcommand "$w.sby set" -font myfont
    scrollbar $w.sbx -orient horizontal -command "$w.t xview"
    scrollbar $w.sby -orient vertical   -command "$w.t yview"

    grid $w.f   -      -sticky news -row 0
    grid $w.t   $w.sby -sticky news
    grid $w.sbx x      -sticky we
    grid columnconfigure $w 0 -weight 1
    grid rowconfigure $w 1 -weight 1

    collectMergeData
    fillMergeWindow
}

#####################################
# Searching
#####################################













proc startIncrementalSearch {w} {





    if {![info exists ::diff(isearch)]} {


        set ::diff(isearch) ""



        set ::diff(isearchlast) ""




    }















    # This shouldn't happen
    if {$::diff(isearch) != ""} {
        endIncrementalSearch $w
    }

    set ::diff(isearch) $w
    

    bind MyText <Control-Key-s> "isearchAgain %W ; break"
    bind MyText <FocusOut> "endIncrementalSearch %W"

    bind MyText <Key> "isearchKey %W %A %s %K"
    bind MyText <Key-Escape> "endIncrementalSearch %W ; break"
    bind MyText <Control-Key-g> "endIncrementalSearch %W ; break"
    bind MyText <Key-Delete> "isearchBack %W ; break"
    bind MyText <Key-BackSpace> "isearchBack %W ; break"

    

    set ::diff(isearchstring) ""
    set ::diff(isearchhistory) {}
    set ::diff(isearchindex) [$w index insert]
    set ::diff(statusLabel) "i"
}


proc isearchShow {w index string} {
    $w tag remove sel 1.0 end
    $w tag add sel $index "$index + [string length $string] chars"
    $w mark set insert $index
    $w see $index

    set ::diff(isearchindex) $index
    set ::diff(isearchstring) $string
    set ::diff(isearchlast) $string
}


proc isearchSearch {w str ix} {

    if {[string equal [string tolower $str] $str]} {
        set found [$w search -nocase $str $ix]
    } else {
        set found [$w search $str $ix]
    }
    return $found
}


proc isearchAgain {w} {

    if {$w != $::diff(isearch)} {
        bell
        endIncrementalSearch $::diff(isearch)
        return
    }

    set str $::diff(isearchstring)
    if {$str == ""} {
        set str $::diff(isearchlast)
    }
    set found [isearchSearch $w $str "$::diff(isearchindex) + 1 char"]
    if {$found == ""} {
        bell
        return
    }
    lappend ::diff(isearchhistory) $::diff(isearchindex) \
            $::diff(isearchstring)
    isearchShow $w $found $str
}


proc isearchKey {w key state sym} {

    if {$w != $::diff(isearch)} {
        bell
        endIncrementalSearch $::diff(isearch)
        return -code break
    }

    if {$key == ""} {
        # Ignore the Control and Shift keys
        if {[string match Contr* $sym]} {return -code break}
        if {[string match Shift* $sym]} {return -code break}
        # Ignore any Control-ed key
        if {$state == 4} {return -code break}
        # Break isearch on other non-ascii keys, and let it through
        bell
        endIncrementalSearch $::diff(isearch)
        return
    }

    set str $::diff(isearchstring)
    append str $key

    set found [isearchSearch $w $str $::diff(isearchindex)]
    if {$found == ""} {
        bell
        return -code break
    }
    lappend ::diff(isearchhistory) $::diff(isearchindex) \
            $::diff(isearchstring)
    isearchShow $w $found $str
    return -code break
}





















































proc isearchBack {w} {





    if {$w != $::diff(isearch)} {


        bell


        endIncrementalSearch $::diff(isearch)








        return




    }
    if {[llength $::diff(isearchhistory)] < 2} {









        bell



        return



    }


    




    set str [lindex $::diff(isearchhistory) end]







    set found [lindex $::diff(isearchhistory) end-1]



    set ::diff(isearchhistory) [lrange $::diff(isearchhistory) 0 end-2]







    

    isearchShow $w $found $str







}






proc endIncrementalSearch {w} {


















    set ::diff(isearch) ""






    set ::diff(statusLabel) ""









    # Remove all bindings from MyText




    foreach b [bind MyText] {





        bind MyText $b ""






    }

    








    bind MyText <Control-Key-s> "startIncrementalSearch %W"









}

#####################################
# Printing stuff
#####################################

# Format a line number for printing







<
<











|


>
>
>
>
>
>




















>
>
>
>
>
>
>
>
>
>
>
>
|
>

>
>
>
|
>
>
|
>
>
>
|
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>


|
|


|

>
|
|
>
|
|
|
<
<
>

>
|
|
|
|


>
|





|
|
|


>
|
>








>
|
>
|

|



|

|

|




|
|



>
|
>
|

|











|



|


|




|
|



>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
|
>
>
>
>
>
|
>
>
|
>
>
|
>
>
>
>
>
>
>
>
|
>
>
>
>
|
|
>
>
>
>
>
>
>
>
>
|
>
>
>
|
>
>
>
|
>
>
|
>
>
>
>
|
>
>
>
>
>
>
>
|
>
>
>
|
>
>
>
>
>
>
>
|
>
|
>
>
>
>
>
>
>
|
>
>
>
>
|
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
>
>
>
>
>
>
|
>

>
>
>
>
>
>
>
|
>
>
>
>
|
>
>
>
>
>
|
>
>
>
>
>
>
|
>
|
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>







1983
1984
1985
1986
1987
1988
1989


1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089


2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
    radiobutton $w.f.rb4 -text "RL" -value 21 -variable curMergeSel \
            -command selectMerge
    bind $w <Key-Left>  {focus .merge ; set curMergeSel 1 ; selectMerge}
    bind $w <Key-Right> {focus .merge ; set curMergeSel 2 ; selectMerge}

    button $w.f.bl -text "All L" -command {selectMergeAll 1}
    button $w.f.br -text "All R" -command {selectMergeAll 2}



    button $w.f.b1 -text "Prev" -command {nextMerge -1}
    button $w.f.b2 -text "Next" -command {nextMerge 1}
    bind $w <Key-Down> {focus .merge ; nextMerge 1}
    bind $w <Key-Up>   {focus .merge ; nextMerge -1}

    button $w.f.bs -text "Save" -command saveMerge
    button $w.f.bq -text "Close" -command closeMerge
    wm protocol $w WM_CLOSE_WINDOW closeMerge

    grid $w.f.rb1 $w.f.rb2 $w.f.rb3 $w.f.rb4 x $w.f.b1 $w.f.b2 x \
            $w.f.bl $w.f.br x x x $w.f.bs $w.f.bq
    grid columnconfigure $w.f {4 7 10 12} -minsize 10
    grid columnconfigure $w.f 10 -weight 1

    if {[string match conflict* $::diff(mode)]} {
        checkbutton $w.f.bm -text "Pure" -variable diff(mode) \
                -onvalue "conflictPure" -offvalue "conflict" -command {doDiff}
        grid $w.f.bm -row 0 -column 11
    }

    text $w.t -width 80 -height 20 -xscrollcommand "$w.sbx set" \
            -yscrollcommand "$w.sby set" -font myfont
    scrollbar $w.sbx -orient horizontal -command "$w.t xview"
    scrollbar $w.sby -orient vertical   -command "$w.t yview"

    grid $w.f   -      -sticky news -row 0
    grid $w.t   $w.sby -sticky news
    grid $w.sbx x      -sticky we
    grid columnconfigure $w 0 -weight 1
    grid rowconfigure $w 1 -weight 1

    collectMergeData
    fillMergeWindow
}

#####################################
# Searching
#####################################

namespace eval textSearch {
    if {![info exists ::textSearch::widgets]} {
        variable widgets {}
    }
    variable isearchW ""
    variable isearchLast ""
    variable searchCase 0
    variable searchIndex 1.0
    variable searchString ""
}

# Setup a text widget for searching
proc textSearch::enableSearch {w} {
    variable widgets

    if {[winfo class $w] != "Text"} {
        error "Only text widgets can be searched!"
    }

    bind ISearch <Control-Key-s> "textSearch::startIncrementalSearch %W"
    bindtags $w "ISearch [bindtags $w]"

    if {[lsearch $widgets $w] < 0} {
        lappend widgets $w
    }

    set top [winfo toplevel $w]
    bind $top <Control-Key-f>  textSearch::search
    bind $top <Key-F3>         textSearch::searchNext
    bind $top <Control-Key-F3> textSearch::searchPrev
}

# Add searching to a menu
proc textSearch::searchMenu {menu} {
    $menu add command -label "Find"      -accelerator "Ctrl+f" \
            -command ::textSearch::search
    $menu add command -label "Find Next" -accelerator "F3" \
            -command ::textSearch::searchNext
    $menu add command -label "Find Prev" -accelerator "Ctrl+F3" \
            -command ::textSearch::searchPrev
}

# Start an incremental search
proc textSearch::startIncrementalSearch {w} {
    variable isearchW

    # This shouldn't happen
    if {$isearchW != ""} {
        endIncrementalSearch
    }

    set isearchW $w
    
    # Setup all bindings for incremental search
    bind ISearch <Control-Key-s> "textSearch::isearchAgain %W ; break"
    bind ISearch <Key-Delete>    "textSearch::isearchBack %W ; break"
    bind ISearch <Key-BackSpace> "textSearch::isearchBack %W ; break"
    bind ISearch <Key>           "textSearch::isearchKey %W %A %s %K"
    bind ISearch <Key-Escape>    "textSearch::endIncrementalSearch ; break"
    bind ISearch <Control-Key-g> "textSearch::endIncrementalSearch ; break"


    bind ISearch <FocusOut>      "textSearch::endIncrementalSearch"
    
    # Initialise variables
    set ::textSearch::isearchString ""
    set ::textSearch::isearchHistory {}
    set ::textSearch::isearchIndex [$w index insert]
    set ::textSearch::statusLabel "i"
}

# Highlight a match
proc textSearch::isearchShow {w index string} {
    $w tag remove sel 1.0 end
    $w tag add sel $index "$index + [string length $string] chars"
    $w mark set insert $index
    $w see $index

    set ::textSearch::isearchIndex $index
    set ::textSearch::isearchString $string
    set ::textSearch::isearchLast $string
}

# Search the widget
proc textSearch::isearchSearch {w str ix} {
    # If the search string is all lower case, search case insensitive
    if {[string equal [string tolower $str] $str]} {
        set found [$w search -nocase $str $ix]
    } else {
        set found [$w search $str $ix]
    }
    return $found
}

# Search for next match
proc textSearch::isearchAgain {w} {
    variable isearchW
    if {$w != $isearchW} {
        bell
        endIncrementalSearch
        return
    }

    set str $::textSearch::isearchString
    if {$str == ""} {
        set str $::textSearch::isearchLast
    }
    set found [isearchSearch $w $str "$::textSearch::isearchIndex + 1 char"]
    if {$found == ""} {
        bell
        return
    }
    lappend ::textSearch::isearchHistory $::textSearch::isearchIndex \
            $::textSearch::isearchString
    isearchShow $w $found $str
}

# A key has been pressed during incremental search
proc textSearch::isearchKey {w key state sym} {
    variable isearchW
    if {$w != $isearchW} {
        bell
        endIncrementalSearch
        return -code break
    }

    if {$key == ""} {
        # Ignore the Control and Shift keys
        if {[string match Contr* $sym]} {return -code break}
        if {[string match Shift* $sym]} {return -code break}
        # Ignore any Control-ed key
        if {$state == 4} {return -code break}
        # Break isearch on other non-ascii keys, and let it through
        bell
        endIncrementalSearch
        return
    }

    set str $::textSearch::isearchString
    append str $key

    set found [isearchSearch $w $str $::textSearch::isearchIndex]
    if {$found == ""} {
        bell
        return -code break
    }
    lappend ::textSearch::isearchHistory $::textSearch::isearchIndex \
            $::textSearch::isearchString
    isearchShow $w $found $str
    return -code break
}

# Go backwards in the isearch stack
proc textSearch::isearchBack {w} {
    variable isearchW
    if {$w != $isearchW} {
        bell
        endIncrementalSearch
        return
    }
    if {[llength $::textSearch::isearchHistory] < 2} {
        bell
        return
    }
    
    set str [lindex $::textSearch::isearchHistory end]
    set found [lindex $::textSearch::isearchHistory end-1]
    set ::textSearch::isearchHistory \
            [lrange $::textSearch::isearchHistory 0 end-2]
    
    isearchShow $w $found $str
}

# End an incremental search
proc textSearch::endIncrementalSearch {} {

    set ::textSearch::isearchW ""
    set ::textSearch::statusLabel ""

    # Remove all bindings from ISearch
    foreach b [bind ISearch] {
        bind ISearch $b ""
    }
    
    bind ISearch <Control-Key-s> "textSearch::startIncrementalSearch %W"
}

# Dialog functions from "Practical Programming in Tcl And Tk" by Welch.
proc textSearch::DialogCreate {top title args} {
    variable dialog
    if {[winfo exists $top]} {
        switch -- [wm state $top] {
            normal {
                # Raise a buried window
                raise $top
            }
            withdrawn -
            iconified {
                # Open and restore geometry
                wm deiconify $top
                catch {wm geometry $top $dialog(geo,$top)}
            }
        }
        return 0
    } else {
        eval {toplevel $top} $args
        wm title $top $title
        return 1
    }
}

proc textSearch::DialogWait {top varName {focus {}}} {
    upvar $varName var
    
    # Poke the variable if the user nukes the window
    bind $top <Destroy> [list set $varName $var]
    
    # Grab focus for the dialog
    if {[string length $focus] == 0} {
        set focus $top
    }
    set old [focus -displayof $top]
    focus $focus
    catch {tkwait visibility $top}
    catch {grab $top}
    
    # Wait for the dialog to complete
    tkwait variable $varName
    catch {grab release $top}
    focus $old
}

proc textSearch::DialogDismiss {top} {
    variable dialog
    # Save current size and position
    catch {
        # window may have been deleted
        set dialog(geo,$top) [wm geometry $top]
        wm withdraw $top
    }
}

# Ask for a search string
proc textSearch::FindDialog {string} {
    variable prompt
    set f .prompt
    if {[DialogCreate $f "Find" -borderwidth 10]} {
        message $f.msg -text $string -aspect 1000
        entry $f.entry -textvariable ::textSearch::prompt(result)
        
        checkbutton $f.case -text "Match Case" -anchor w\
                -variable ::textSearch::searchCase
        
        button $f.ok     -text OK     -width 7 \
                -command {set ::textSearch::prompt(ok) 1}
        button $f.cancel -text Cancel -width 7 \
                -command {set ::textSearch::prompt(ok) 0}

        grid $f.msg   - - -sticky w
        grid $f.entry - - -sticky we
        grid $f.case  - - -sticky w
        grid $f.ok x $f.cancel -sticky wes
        grid columnconfigure $f {0 2} -weight 1
        grid columnconfigure $f 1 -minsize 10 -weight 2
        grid rowconfigure $f 3 -weight 1

        bind $f.entry <Key-Return> {set ::textSearch::prompt(ok) 1 ; break}
        bind $f.entry <Key-Escape> {set ::textSearch::prompt(ok) 0 ; break}
    }

    set prompt(ok) 0
    DialogWait $f ::textSearch::prompt(ok) $f.entry
    DialogDismiss $f
    if {$prompt(ok)} {
        return $prompt(result)
    } else {
        return {}
    }
}

# "Normal" search
proc textSearch::search {} {
    variable searchString
    variable searchWin
    variable widgets
    variable searchCase
    variable searchIndex

    set searchWin [lindex $widgets 0]
    set foc [focus -displayof .]
    if {[lsearch $widgets $foc] >= 0} {
        set searchWin $foc
    }
    set searchString [FindDialog "Please enter string to find"]

    if {$searchString == ""} return

    if {$searchCase} {
        set searchPos [$searchWin search -count cnt $searchString @0,0]
    } else {
        set searchPos [$searchWin search -count cnt -nocase $searchString @0,0]
    }
    if {$searchPos == ""} {
        tk_messageBox -message "Search string not found!" -type ok \
                -title Search
        return
    }

    $searchWin see $searchPos
    $searchWin tag remove sel 1.0 end
    $searchWin tag add sel $searchPos "$searchPos + $cnt chars"
    set searchIndex $searchPos
}      

# Search again
proc textSearch::searchNext {} {
    variable searchString
    variable searchWin
    variable searchCase
    variable searchIndex

    if {$searchString == ""} return

    if {$searchCase} {
        set searchPos [$searchWin search -count cnt \
                $searchString "$searchIndex + 1 chars"]
    } else {
        set searchPos [$searchWin search -count cnt -nocase \
                $searchString "$searchIndex + 1 chars"]
    }
    
    if {$searchPos == "" || $searchPos == $searchIndex} {
        tk_messageBox -message "String not found!" -type ok -title Search
        return
    }

    $searchWin see $searchPos
    $searchWin tag remove sel 1.0 end
    $searchWin tag add sel $searchPos "$searchPos + $cnt chars"
    set searchIndex $searchPos
}

# Search backwards
proc textSearch::searchPrev {} {
    variable searchString
    variable searchWin
    variable searchCase
    variable searchIndex

    if {$searchString == ""} return

    if {$searchCase} {
        set searchPos [$searchWin search -count cnt -backwards \
                $searchString "$searchIndex - 1 chars"]
    } else {
        set searchPos [$searchWin search -count cnt -backwards \
                -nocase \
                $searchString "$searchIndex - 1 chars"]
    }
    
    if {$searchPos == "" || $searchPos == $searchIndex} {
        tk_messageBox -message "String not found!" -type ok -title Search
        return
    }

    $searchWin see $searchPos
    $searchWin tag remove sel 1.0 end
    $searchWin tag add sel $searchPos "$searchPos + $cnt chars"
    set searchIndex $searchPos
}

#####################################
# Printing stuff
#####################################

# Format a line number for printing
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
}

# Main print function
proc printDiffs {{quiet 0}} {
    busyCursor
    update idletasks
    set tmpFile [file nativename ~/tcldiff.enscript]
    set tmpFile2 [file nativename ~/tcldifftmp.ps]
    if {$::diff(printFile) != ""} {
        set tmpFile3 [file nativename $::diff(printFile)]
    } else {
        set tmpFile3 [file nativename ~/tcldiff.ps]
    }

    set lines1 {}
    set lines2 {}

    set tdump1 [.ft1.tt dump -tag -text 1.0 end]
    set tdump2 [.ft2.tt dump -tag -text 1.0 end]







<

|

|







2475
2476
2477
2478
2479
2480
2481

2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
}

# Main print function
proc printDiffs {{quiet 0}} {
    busyCursor
    update idletasks
    set tmpFile [file nativename ~/tcldiff.enscript]

    if {$::diff(printFile) != ""} {
        set tmpFile2 [file nativename $::diff(printFile)]
    } else {
        set tmpFile2 [file nativename ~/tcldiff.ps]
    }

    set lines1 {}
    set lines2 {}

    set tdump1 [.ft1.tt dump -tag -text 1.0 end]
    set tdump2 [.ft2.tt dump -tag -text 1.0 end]
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
    }
    set rfile [file tail $rfile]$rrest

    lappend enscriptCmd "--header=$lfile|Page \$% of \$=|$rfile"
    if {$::prettyPrint != ""} {
        lappend enscriptCmd -E$::prettyPrint
    }
    lappend enscriptCmd -p $tmpFile3 $tmpFile

    if {[catch {eval exec $enscriptCmd} result]} {
        if {[string index $result 0] != "\["} {
            tk_messageBox -message "Enscript error: $result"
            return
        }
    }

    normalCursor
    if {!$quiet} {
        destroy .dp
        toplevel .dp
        wm title .dp "Diff Print"
        button .dp.b -text Close -command {destroy .dp}
        label .dp.l -anchor w -justify left -text "The following files have\
                been created:\n\n$tmpFile\nInput file to enscript.\
                \n\n$tmpFile3\nCreated with\
                '[lrange $enscriptCmd 0 end-3] \\\n             \
                [lrange $enscriptCmd end-2 end]'" \
                -font "Courier 8"
        pack .dp.b -side bottom
        pack .dp.l -side top
    }
}







|
















|







2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
    }
    set rfile [file tail $rfile]$rrest

    lappend enscriptCmd "--header=$lfile|Page \$% of \$=|$rfile"
    if {$::prettyPrint != ""} {
        lappend enscriptCmd -E$::prettyPrint
    }
    lappend enscriptCmd -p $tmpFile2 $tmpFile

    if {[catch {eval exec $enscriptCmd} result]} {
        if {[string index $result 0] != "\["} {
            tk_messageBox -message "Enscript error: $result"
            return
        }
    }

    normalCursor
    if {!$quiet} {
        destroy .dp
        toplevel .dp
        wm title .dp "Diff Print"
        button .dp.b -text Close -command {destroy .dp}
        label .dp.l -anchor w -justify left -text "The following files have\
                been created:\n\n$tmpFile\nInput file to enscript.\
                \n\n$tmpFile2\nCreated with\
                '[lrange $enscriptCmd 0 end-3] \\\n             \
                [lrange $enscriptCmd end-2 end]'" \
                -font "Courier 8"
        pack .dp.b -side bottom
        pack .dp.l -side top
    }
}
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
    .mo.mp add separator
    .mo.mp add checkbutton -label "Use 2nd stage" \
            -variable Pref(extralineparse)
    .mo.mp add checkbutton -label "Mark last" -variable Pref(marklast)

    menubutton .ms -text Search -underline 0 -menu .ms.m 
    menu .ms.m
    .ms.m add command -label "Find"      -accelerator "Ctrl+f" -command Search
    .ms.m add command -label "Find Next" -accelerator "F3" \
            -command SearchNext
    .ms.m add command -label "Find Prev" -accelerator "Ctrl+F3" \
            -command SearchPrev

    menubutton .mh -text Help -underline 0 -menu .mh.m
    menu .mh.m
    .mh.m add command -label "Help" -command makeHelpWin
    .mh.m add command -label "About" -command makeAboutWin

    button .bfn -text "Next Diff" -relief raised -command {findDiff 1}







<
<
|
<
<







2924
2925
2926
2927
2928
2929
2930


2931


2932
2933
2934
2935
2936
2937
2938
    .mo.mp add separator
    .mo.mp add checkbutton -label "Use 2nd stage" \
            -variable Pref(extralineparse)
    .mo.mp add checkbutton -label "Mark last" -variable Pref(marklast)

    menubutton .ms -text Search -underline 0 -menu .ms.m 
    menu .ms.m


    textSearch::searchMenu .ms.m



    menubutton .mh -text Help -underline 0 -menu .mh.m
    menu .mh.m
    .mh.m add command -label "Help" -command makeHelpWin
    .mh.m add command -label "About" -command makeAboutWin

    button .bfn -text "Next Diff" -relief raised -command {findDiff 1}
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
    text .ft2.tt -height 60 -width 80 -wrap none -yscrollcommand my_yscroll \
            -xscrollcommand ".sbx2 set" -font myfont -borderwidth 0 -padx 0 \
            -highlightthickness 0
    pack .ft2.tl -side left -fill y
    pack .ft2.tt -side right -fill both -expand 1
    scrollbar .sbx2 -orient horizontal -command ".ft2.tt xview"

    bind MyText <Control-Key-s> "startIncrementalSearch %W"
    bindtags .ft1.tt "MyText [bindtags .ft1.tt]"
    bindtags .ft2.tt "MyText [bindtags .ft2.tt]"

    label .le -textvariable ::diff(eqLabel) -width 1
    label .ls -textvariable ::diff(statusLabel) -width 1 -pady 0 -padx 0
    canvas .c -width 6 -bd 0 -selectborderwidth 0 -highlightthickness 0

    applyColor
    .ft1.tt tag configure last -underline 1
    .ft2.tt tag configure last -underline 1
    foreach w {.ft1.tt .ft1.tl .ft2.tt .ft2.tl} {
        bind $w <ButtonPress-3> "zoomRow %W %X %Y %x %y"







|
|
|


|







2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
    text .ft2.tt -height 60 -width 80 -wrap none -yscrollcommand my_yscroll \
            -xscrollcommand ".sbx2 set" -font myfont -borderwidth 0 -padx 0 \
            -highlightthickness 0
    pack .ft2.tl -side left -fill y
    pack .ft2.tt -side right -fill both -expand 1
    scrollbar .sbx2 -orient horizontal -command ".ft2.tt xview"

    # Set up a tag for incremental search bindings
    textSearch::enableSearch .ft1.tt
    textSearch::enableSearch .ft2.tt

    label .le -textvariable ::diff(eqLabel) -width 1
    label .ls -textvariable ::textSearch::statusLabel -width 1 -pady 0 -padx 0
    canvas .c -width 6 -bd 0 -selectborderwidth 0 -highlightthickness 0

    applyColor
    .ft1.tt tag configure last -underline 1
    .ft2.tt tag configure last -underline 1
    foreach w {.ft1.tt .ft1.tl .ft2.tt .ft2.tl} {
        bind $w <ButtonPress-3> "zoomRow %W %X %Y %x %y"
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
    bind .c <Configure> {drawMap %h}

    bind . <Key-Up> {scroll -1 u}
    bind . <Key-Down> {scroll 1 u}
    bind . <Key-Prior> {scroll -1 p}
    bind . <Key-Next> {scroll 1 p}
    bind . <Key-Escape> {focus .}
    bind . <Control-Key-f> {Search}
    bind . <Key-F3> {SearchNext}
    bind . <Control-Key-F3> {SearchPrev}

    pack .mf .mo .ms .mh -in .f -side left
    pack .bfn .bfp .eo .lo -in .f -side right
    if {$debug == 1} {
        menubutton .md -text Debug -menu .md.m -relief ridge
        menu .md.m
        if {$tcl_platform(platform) == "windows"} {







<
<
<







2995
2996
2997
2998
2999
3000
3001



3002
3003
3004
3005
3006
3007
3008
    bind .c <Configure> {drawMap %h}

    bind . <Key-Up> {scroll -1 u}
    bind . <Key-Down> {scroll 1 u}
    bind . <Key-Prior> {scroll -1 p}
    bind . <Key-Next> {scroll 1 p}
    bind . <Key-Escape> {focus .}




    pack .mf .mo .ms .mh -in .f -side left
    pack .bfn .bfp .eo .lo -in .f -side right
    if {$debug == 1} {
        menubutton .md -text Debug -menu .md.m -relief ridge
        menu .md.m
        if {$tcl_platform(platform) == "windows"} {
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636

if {![winfo exists .f]} {
    getOptions
    makeDiffWin
    update idletasks
    parseCommandLine
}

# Searching contributed by Ulf Nilsson
# FIXA, test this properly and incorporate into the rest of the file

# Dialog functions from "Practical Programming in Tcl And Tk" by Welch.
proc Dialog_Create {top title args} {
    global dialog
    if {[winfo exists $top]} {
        switch -- [wm state $top] {
            normal {
                # Raise a buried window
                raise $top
            }
            withdrawn -
            iconified {
                # Open and restore geometry
                wm deiconify $top
                catch {wm geometry $top $dialog(geo,$top)}
            }
        }
        return 0
    } else {
        eval {toplevel $top} $args
        wm title $top $title
        return 1
    }
}

proc Dialog_Wait {top varName {focus {}}} {
    upvar $varName var
    
    # Poke the variable if the user nukes the window
    bind $top <Destroy> [list set $varName $var]
    
    # Grab focus for the dialog
    if {[string length $focus] == 0} {
        set focus $top
    }
    set old [focus -displayof $top]
    focus $focus
    catch {tkwait visibility $top}
    catch {grab $top}
    
    # Wait for the dialog to complete
    tkwait variable $varName
    catch {grab release $top}
    focus $old
}

proc Dialog_Dismiss {top} {
    global dialog
    # Save current size and position
    catch {
        # window may have been deleted
        set dialog(geo,$top) [wm geometry $top]
        wm withdraw $top
    }
}

proc Find_Dialog { string } {
    global prompt CaseSensitive
    set f .prompt
    if {[Dialog_Create $f "Find" -borderwidth 10]} {
        message $f.msg -text $string -aspect 1000
        entry $f.entry -textvariable prompt(result)
        
        checkbutton $f.case -text "Match Case" -variable ::diff(searchcase)
        pack $f.case -side right
        
        set b [frame $f.buttons]
        pack $f.msg $f.entry $f.buttons -side top -fill x
        pack $f.entry -pady 5
        button $b.ok -text OK -command {set prompt(ok) 1}
        button $b.cancel -text Cancel \
                -command {set prompt(ok) 0}
		
		
        pack $b.ok -side left
        pack $b.cancel -side right
        bind $f.entry <Return> {set prompt(ok) 1 ; break}
        bind $f.entry <Key-Escape> {set prompt(ok) 0 ; break}
        
    }
    set prompt(ok) 0
    Dialog_Wait $f prompt(ok) $f.entry
    Dialog_Dismiss $f
    if {$prompt(ok)} {
        return $prompt(result)
    } else {
        return {}
    }
}

proc Search {} {
    if {![info exists diff(searchcase)]} {
        set ::diff(searchcase) 0
        set ::diff(searchindex) 1.0
        set ::diff(searchstring) ""
    }

    set ::diff(searchwin) .ft1.tt
    if {[focus -displayof .] == ".ft2.tt"} {
        set ::diff(searchwin) .ft2.tt
    }
    set ::diff(searchstring) [Find_Dialog "Please enter string to find"]

    if {$::diff(searchcase)} {
        set searchpos [$::diff(searchwin) search -count cnt \
                $::diff(searchstring) @0,0]
    } else {
        set searchpos [$::diff(searchwin) search -count cnt -nocase \
                $::diff(searchstring) @0,0]
    }
    if {$searchpos == ""} {
        tk_messageBox -message "Search string not found!" -type ok -title Diff
        return
    }

    $::diff(searchwin) see $searchpos
    $::diff(searchwin) tag remove sel 1.0 end
    $::diff(searchwin) tag add sel $searchpos "$searchpos + $cnt chars"
    set ::diff(searchindex) $searchpos
}      

proc SearchNext {} {
    if {$::diff(searchcase)} {
        set searchpos [$::diff(searchwin) search -count cnt \
                $::diff(searchstring) "$::diff(searchindex) + 1 chars"]
    } else {
        set searchpos [$::diff(searchwin) search -count cnt -nocase \
                $::diff(searchstring) "$::diff(searchindex) + 1 chars"]
    }
    
    if {$searchpos == "" || $searchpos == $::diff(searchindex)} {
        tk_messageBox -message "String not found!" -type ok -title Diff
        return
    }

    $::diff(searchwin) see $searchpos
    $::diff(searchwin) tag remove sel 1.0 end
    $::diff(searchwin) tag add sel $searchpos "$searchpos + $cnt chars"
    set ::diff(searchindex) $searchpos
}

proc SearchPrev {} {
    if {$::diff(searchcase)} {
        set searchpos [$::diff(searchwin) search -count cnt -backwards \
                $::diff(searchstring) "$::diff(searchindex) - 1 chars"]
    } else {
        set searchpos [$::diff(searchwin) search -count cnt -backwards \
                -nocase \
                $::diff(searchstring) "$::diff(searchindex) - 1 chars"]
    }
    
    if {$searchpos == "" || $searchpos == $::diff(searchindex)} {
        tk_messageBox -message "String not found!" -type ok -title Diff
        return
    }

    $::diff(searchwin) see $searchpos
    $::diff(searchwin) tag remove sel 1.0 end
    $::diff(searchwin) tag add sel $searchpos "$searchpos + $cnt chars"
    set ::diff(searchindex) $searchpos
}







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
3737
3738
3739
3740
3741
3742
3743





































































































































































if {![winfo exists .f]} {
    getOptions
    makeDiffWin
    update idletasks
    parseCommandLine
}