︙ | | |
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
-
+
|
# cleanupAndExit can be used to get rid of it.
proc eskilRegisterToplevel {top} {
lappend ::eskil(diffWindows) $top
}
# Format a line number
proc myFormL {lineNo} {
if {![string is integer -strict $lineNo]} {return "$lineNo\n"}
if { ! [string is integer -strict $lineNo]} {return "$lineNo\n"}
return [format "%3d: \n" $lineNo]
}
# Get a name for a temporary file
# A tail can be given to make the file more recognisable.
proc tmpFile {{tail {}}} {
if {[info exists ::tmpcnt]} {
|
︙ | | |
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
-
+
|
set name [file join $::eskil(tmpdir) $name]
lappend ::tmpfiles $name
return $name
}
# Delete temporary files
proc clearTmp {args} {
if {![info exists ::tmpfiles]} {
if { ! [info exists ::tmpfiles]} {
set ::tmpfiles {}
return
}
if {[llength $args] > 0} {
foreach f $args {
set i [lsearch -exact $::tmpfiles $f]
if {$i >= 0} {
|
︙ | | |
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
|
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
|
-
+
-
+
-
+
|
# insertLine, when in table mode
proc insertLineTable {top side line text {tag equal}} {
set RE $::eskil($top,separator)
set words [split $text $RE]
set id [$::widgets($top,wTable) insert end $words]
if {$tag ne "equal"} {
set col 0
foreach w $words {
foreach word $words {
if {$side == 1} {
# TBD TABLE, r is faked here for now
dict set ::eskil($top,tablechanges) $id,$col w1 $w
dict set ::eskil($top,tablechanges) $id,$col w1 $word
dict set ::eskil($top,tablechanges) $id,$col w2 ""
dict set ::eskil($top,tablechanges) $id,$col r "0 0 1 1"
} else {
dict set ::eskil($top,tablechanges) $id,$col w1 ""
dict set ::eskil($top,tablechanges) $id,$col w2 $w
dict set ::eskil($top,tablechanges) $id,$col w2 $word
dict set ::eskil($top,tablechanges) $id,$col r "0 0 1 1"
}
incr col
}
}
}
|
︙ | | |
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
|
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
|
-
+
-
+
-
+
-
+
-
-
+
+
-
+
-
+
|
}
#puts "RES '$res'"
return $res
}
# This is called from the table view whenever a cell is drawn.
# Add color as needed.
proc tblModeColorCallback {win w key row col tabIdx1 tabIdx2 inStripe selected} {
proc tblModeColorCallback {win W key row col tabIdx1 tabIdx2 inStripe selected} {
set cellX $key,$col
set top [winfo toplevel $win]
if {![dict exists $::eskil($top,tablechanges) $cellX]} {
if { ! [dict exists $::eskil($top,tablechanges) $cellX]} {
# No changes, nothing to do here
return
}
set cinfo [dict get $::eskil($top,tablechanges) $cellX]
set w1 [dict get $cinfo w1]
set w2 [dict get $cinfo w2]
#puts "COLOR UPDATE W $win K $key R $row C $col TB1 $tabIdx1 TB2 $tabIdx2"
#puts " [string length $xxx] '$xxx'"
#puts " CHANGEME"
# Currently the displayed string is just $w1$w2
# The table might have cut of display of a cell so make sure to stay
# within the boundaries.
set txIdx1 [$w index $tabIdx1+1c]
set txIdx1 [$W index $tabIdx1+1c]
set l1 [string length $w1]
set mid "$txIdx1 + $l1 char"
if {[$w compare $mid >= $tabIdx2]} {
if {[$W compare $mid >= $tabIdx2]} {
set mid $tabIdx2
}
$w tag add new1 $txIdx1 $mid
$w tag add new2 $mid $tabIdx2
$W tag add new1 $txIdx1 $mid
$W tag add new2 $mid $tabIdx2
# Get the displayed string
set xxx [$w get $txIdx1 $tabIdx2]
set xxx [$W get $txIdx1 $tabIdx2]
if {$xxx ne "$w1$w2"} {
# Make sure dots are coloured
$w tag add change "$tabIdx2 - 3c" $tabIdx2
$W tag add change "$tabIdx2 - 3c" $tabIdx2
}
}
# insertMatchingLines, when in table mode
proc insertMatchingLinesTable {top line1 line2} {
global doingLine1 doingLine2
|
︙ | | |
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
|
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
|
-
+
|
set block1nostar [string map {* {}} $block1nospace]
set block2nostar [string map {* {}} $block2nospace]
if {$block1nostar eq $block2nostar} {
set equal 1
}
}
}
if {!$equal} {
if { ! $equal} {
return 0
}
if {$visible} {
set tag change
} else {
set tag {}
|
︙ | | |
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
|
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
|
-
+
-
+
|
if {$::eskil($top,ancestorRight,$t) eq "c"} {
set rightChange 1
break
}
}
}
# Avoid fine grain if either side has no changes against ancestor
if {!$leftChangeOrAdd || !$rightChangeOrAdd} {
if { ! $leftChangeOrAdd || !$rightChangeOrAdd} {
set finegrain 0
}
# Avoid fine grain if both sides have at most additions
if {!$leftChange && !$rightChange} {
if { ! $leftChange && !$rightChange} {
set finegrain 0
}
}
set t1 0
set t2 0
foreach c $apa {
|
︙ | | |
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
|
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
|
-
+
|
addChange $top 1 new2 [expr {$line1 + $t1}] 0 \
[expr {$line2 + $t2}] 1
nextHighlight $top
}
incr t2
}
}
if {!$finegrain} {
if { ! $finegrain} {
if {$details} {
addChange $top [llength $apa] change $line1 $n1 $line2 $n2
nextHighlight $top
} else {
addMapLines $top [llength $apa]
}
}
|
︙ | | |
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
872
873
874
875
|
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
872
873
874
875
|
-
+
-
-
+
+
-
-
+
+
|
proc busyCursor {top} {
global oldcursor oldcursor2
if {$::eskil($top,view) eq "table"} {
set items wTable
} else {
set items {wLine1 wDiff1 wLine2 wDiff2}
}
if {![info exists oldcursor]} {
if { ! [info exists oldcursor]} {
set oldcursor [$top cget -cursor]
set i1 [lindex $items 0]
set oldcursor2 [$::widgets($top,$i1) cget -cursor]
}
$top config -cursor watch
foreach item $items {
if {[info exists ::widgets($top,$item)]} {
set w $::widgets($top,$item)
$w config -cursor watch
set W $::widgets($top,$item)
$W config -cursor watch
}
}
}
proc normalCursor {top} {
global oldcursor oldcursor2
if {$::eskil($top,view) eq "table"} {
set items wTable
} else {
set items {wLine1 wDiff1 wLine2 wDiff2}
}
$top config -cursor $oldcursor
foreach item $items {
if {[info exists ::widgets($top,$item)]} {
set w $::widgets($top,$item)
$w config -cursor $oldcursor2
set W $::widgets($top,$item)
$W config -cursor $oldcursor2
}
}
}
#####################################
# Special cases. Conflict/patch
#####################################
|
︙ | | |
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
|
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
|
-
+
-
+
-
+
|
if {[regexp {^---\s*(\d*)} $line -> sub]} {
if {$sub != ""} {
set rightLine $sub
}
set state right
continue
}
if {![regexp {^[\s!+-]} $line]} continue
if { ! [regexp {^[\s!+-]} $line]} continue
lappend leftLines [list $leftLine \
[string trim [string range $line 0 1]] \
[string range $line 2 end]]
incr leftLine
continue
}
# We are in the right part of a -c style diff
if {$state eq "right"} {
if {![regexp {^[\s!+-]} $line]} continue
if { ! [regexp {^[\s!+-]} $line]} continue
lappend rightLines [list $rightLine \
[string trim [string range $line 0 1]] \
[string range $line 2 end]]
incr rightLine
continue
}
# We are in a -u style diff
if {$state eq "both"} {
if {![regexp {^[\s+-]} $line]} continue
if { ! [regexp {^[\s+-]} $line]} continue
set sig [string trim [string index $line 0]]
set str [string range $line 1 end]
if {$sig eq ""} {
lappend leftLines [list $leftLine "" $str]
lappend rightLines [list $rightLine "" $str]
incr leftLine
incr rightLine
|
︙ | | |
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
|
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
|
-
-
+
+
-
+
-
+
-
-
+
+
|
#####################################
# Main diff
#####################################
proc highlightTabs {top} {
foreach item {wDiff1 wDiff2} {
set w $::widgets($top,$item)
##nagelfar vartype w _obj,text
set W $::widgets($top,$item)
##nagelfar vartype W _obj,text
set count {}
set x [$w search -regexp -all -count count {\t+} 1.0]
set x [$W search -regexp -all -count count {\t+} 1.0]
foreach si $x l $count {
$w tag add tab $si "$si + $l chars"
$W tag add tab $si "$si + $l chars"
}
$w tag configure tab -background bisque
$w tag raise tab
$W tag configure tab -background bisque
$W tag raise tab
}
}
# Prepare for a diff by creating needed temporary files
proc prepareFiles {top} {
set ::eskil($top,cleanup) {}
if {$::eskil($top,mode) eq "rev"} {
|
︙ | | |
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
|
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
|
-
+
-
-
+
+
-
-
+
+
-
-
+
+
|
# TBD TABLE
doDiff $top
# Restore view
return
}
# Note what rows are being displayed
set w $::widgets($top,wDiff1)
set W $::widgets($top,wDiff1)
set width [winfo width $w]
set height [winfo height $w]
set width [winfo width $W]
set height [winfo height $W]
set first [$w index @0,0]
set last [$w index @[- $width 4],[- $height 4]]
set first [$W index @0,0]
set last [$W index @[- $width 4],[- $height 4]]
set first [lindex [split $first .] 0]
set last [lindex [split $last .] 0]
# Narrow it 5 lines since seeText will try to view 5 lines extra
incr first 5
incr last -5
if {$last < $first} {
set last $first
}
doDiff $top
# Restore view
foreach item {wLine1 wDiff1 wLine2 wDiff2} {
set w $::widgets($top,$item)
seeText $w $first.0 $last.0
set W $::widgets($top,$item)
seeText $W $first.0 $last.0
}
}
# Make an appropriate tail for a window title, depending on mode and files.
proc TitleTail {top} {
set tail1 [file tail $::eskil($top,rightLabel)]
set tail2 [file tail $::eskil($top,leftLabel)]
|
︙ | | |
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
|
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
|
-
+
-
-
+
+
-
-
-
+
+
+
-
-
+
+
|
}
busyCursor $top
resetEdit $top
# Clear up everything before starting processing
if {$::eskil($top,view) eq "table"} {
set w $::widgets($top,wTable)
set W $::widgets($top,wTable)
# TBD TABLE
$w configure -state normal
$w delete 0 end
$W configure -state normal
$W delete 0 end
set ::eskil($top,tablechanges) {}
} else {
foreach item {wLine1 wDiff1 wLine2 wDiff2 wTb} {
set w $::widgets($top,$item)
$w configure -state normal
$w delete 1.0 end
set W $::widgets($top,$item)
$W configure -state normal
$W delete 1.0 end
}
}
clearMap $top
set ::HighLightCount 0
highLightChange $top -1
# Display a star during diff execution, to know when the internal
# processing starts, and when the label is "valid".
set ::widgets($top,eqLabel) "*"
wm title $top "Eskil:"
update idletasks
if {$::eskil($top,mode) eq "patch"} {
disallowEdit $top
displayPatch $top
drawMap $top -1
#drawEditButtons $top
foreach item {wLine1 wLine2} {
set w $::widgets($top,$item)
$w configure -state disabled
set W $::widgets($top,$item)
$W configure -state disabled
}
update idletasks
wm title $top "Eskil: [file tail $::eskil($top,patchFile)]"
# TBD TABLE
$::widgets($top,wLine2) see 1.0
if {$::eskil($top,printFileCmd) && $::eskil($top,printFile) ne ""} {
after idle "doPrint $top 1 ; cleanupAndExit all"
|
︙ | | |
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
|
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
|
-
-
-
+
+
+
-
-
+
+
-
+
|
doText $top $ch1 $ch2 0 0 $end1 $end2
if {$::eskil($top,view) ne "table"} {
# Make sure all text widgets have the same number of lines.
# The common y scroll doesn't work well if not.
set max 0.0
foreach item {wLine1 wDiff1 wLine2 wDiff2} {
set w $::widgets($top,$item)
if {[$w index end] > $max} {
set max [$w index end]
set W $::widgets($top,$item)
if {[$W index end] > $max} {
set max [$W index end]
}
}
foreach item {wLine1 wDiff1 wLine2 wDiff2} {
set w $::widgets($top,$item)
set d [expr {int($max) - int([$w index end])}]
set W $::widgets($top,$item)
set d [expr {int($max) - int([$W index end])}]
for {set t 0} {$t < $d} {incr t} {
$w insert end \n padding
$W insert end \n padding
}
}
}
close $ch1
close $ch2
|
︙ | | |
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
|
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
|
-
-
+
+
|
}
}
drawMap $top -1
#drawEditButtons $top
if {$::eskil($top,view) ne "table"} {
foreach item {wLine1 wLine2 wTb} {
set w $::widgets($top,$item)
$w configure -state disabled
set W $::widgets($top,$item)
$W configure -state disabled
}
update idletasks
$::widgets($top,wLine2) see 1.0
}
normalCursor $top
showDiff $top 0
if {$::widgets($top,eqLabel) eq "!"} {
|
︙ | | |
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
|
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
|
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
+
+
|
# Scroll windows to next/previous diff
proc findDiff {top delta} {
showDiff $top [expr {$::eskil($top,currHighLight) + $delta}]
}
# Scroll a text window to view a certain range, and possibly some
# lines before and after.
proc seeText {w si ei} {
$w see $ei
$w see $si
$w see $si-5lines
$w see $ei+5lines
if {[llength [$w bbox $si]] == 0} {
$w yview $si-5lines
proc seeText {W si ei} {
$W see $ei
$W see $si
$W see $si-5lines
$W see $ei+5lines
if {[llength [$W bbox $si]] == 0} {
$W yview $si-5lines
}
if {[llength [$w bbox $ei]] == 0} {
$w yview $si
if {[llength [$W bbox $ei]] == 0} {
$W yview $si
}
}
# Highlight a diff
proc highLightChange {top changeIndex} {
if {[info exists ::eskil($top,currHighLight)] && \
$::eskil($top,currHighLight) >= 0} {
|
︙ | | |
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
|
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
|
-
-
+
+
|
set line2 [expr {$line1 + [lindex $change 1]}]
incr line1
set line1 $line1.0
set line2 $line2.0
}
foreach item {wLine1 wDiff1 wLine2 wDiff2} {
set w $::widgets($top,$item)
seeText $w $line1 $line2
set W $::widgets($top,$item)
seeText $W $line1 $line2
}
}
#####################################
# Editing
#####################################
|
︙ | | |
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
|
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
|
-
-
-
-
+
+
+
+
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
-
-
+
+
-
+
-
+
-
-
-
+
+
+
-
+
|
return
}
resetEditW $::widgets($top,wDiff1)
resetEditW $::widgets($top,wDiff2)
}
# Clear Editing state for a Text widget
proc resetEditW {w} {
$w tag configure padding -background {}
$w edit reset
$w configure -undo 0
proc resetEditW {W} {
$W tag configure padding -background {}
$W edit reset
$W configure -undo 0
set ::eskil($w,allowChange) all
set ::eskil($W,allowChange) all
wcb::callback $w before insert {}
wcb::callback $w before delete {}
wcb::callback $W before insert {}
wcb::callback $W before delete {}
}
# Do not allow any editing
proc noEdit {top} {
if {$::eskil($top,view) eq "table"} {
return
}
noEditW $::widgets($top,wDiff1)
noEditW $::widgets($top,wDiff2)
}
# Do not allow any editing in a Text widget
proc noEditW {w} {
set ::eskil($w,allowChange) none
proc noEditW {W} {
set ::eskil($W,allowChange) none
wcb::callback $w before insert [list TextInterceptInsert $w]
wcb::callback $w before delete [list TextInterceptDelete $w]
wcb::callback $W before insert [list TextInterceptInsert $W]
wcb::callback $W before delete [list TextInterceptDelete $W]
}
proc TextInterceptInsert {w ow index str args} {
if {$::eskil($w,allowChange) eq "none"} {
proc TextInterceptInsert {W oW index str args} {
if {$::eskil($W,allowChange) eq "none"} {
wcb::cancel
return
}
if {$::eskil($w,allowChange) eq "all"} return
if {$::eskil($W,allowChange) eq "all"} return
#wcb::cancel - Cancel a widget command
#wcb::replace - Replace arguments of a widget command with new ones
# Disallow all new lines
if {[string first "\n" $str] >= 0} {
wcb::cancel
return
}
foreach {tag str2} $args {
if {[string first "\n" $str2] >= 0} {
wcb::cancel
return
}
}
}
proc TextInterceptDelete {w ow from {to {}}} {
if {$::eskil($w,allowChange) eq "none"} {
proc TextInterceptDelete {W oW from {to {}}} {
if {$::eskil($W,allowChange) eq "none"} {
wcb::cancel
return
}
if {$::eskil($w,allowChange) eq "all"} return
if {$::eskil($W,allowChange) eq "all"} return
if {$to eq ""} {
set to $from+1char
}
set text [$ow get $from $to]
set text [$oW get $from $to]
# Disallow all new lines
if {[string first "\n" $text] >= 0} {
wcb::cancel
return
}
}
# Turn on editing for a Text widget
proc turnOnEdit {w} {
$w tag configure padding -background \#f0f0f0
$w configure -undo 1
proc turnOnEdit {W} {
$W tag configure padding -background \#f0f0f0
$W configure -undo 1
set ::eskil($w,allowChange) line
set ::eskil($W,allowChange) line
}
# Turn on editing on sides where it has not been disallowed
proc allowEdit {top} {
$top.m.mt entryconfigure "Edit Mode" -state disable
if {$::eskil($top,leftEdit) == 0} {
set ::eskil($top,leftEdit) 1
|
︙ | | |
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
|
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
|
-
-
+
+
-
+
-
-
-
-
+
+
+
+
|
} else {
return [expr {$::eskil($top,rightEdit) == 1}]
}
}
# Start an undo block in a bunch of text widgets
proc startUndoBlock {args} {
foreach w $args {
$w configure -autoseparators 0
foreach W $args {
$W configure -autoseparators 0
# Open up editing for copy functions
set ::eskil($w,allowChange) all
set ::eskil($W,allowChange) all
}
}
# End an undo block in a bunch of text widgets
proc endUndoBlock {args} {
foreach w $args {
$w configure -autoseparators 1
$w edit separator
set ::eskil($w,allowChange) line
foreach W $args {
$W configure -autoseparators 1
$W edit separator
set ::eskil($W,allowChange) line
}
}
# Copy a block
proc copyBlock {top from first last} {
set to [expr {$from == 1 ? 2 : 1}]
|
︙ | | |
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
|
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
|
-
+
-
-
-
-
+
+
+
+
-
+
-
+
-
+
-
+
-
-
+
+
-
+
-
-
+
+
-
+
-
+
-
+
-
-
+
+
-
-
+
+
-
+
-
+
-
+
-
-
+
+
-
+
-
+
-
+
|
$wfrom insert $row.0 $text ""
endUndoBlock $wfrom $wto
}
# Delete a row filling it with padding
proc deleteBlock {top side from {to {}}} {
set w $::widgets($top,wDiff$side)
set W $::widgets($top,wDiff$side)
if {$to eq ""} {set to $from}
startUndoBlock $w
$w delete $from.0 $to.end+1c
$w insert $from.0 [string repeat \n [expr {$to - $from + 1}]] padding
endUndoBlock $w
startUndoBlock $W
$W delete $from.0 $to.end+1c
$W insert $from.0 [string repeat \n [expr {$to - $from + 1}]] padding
endUndoBlock $W
}
# Get the lines involved in the display
proc getLinesFromRange {w range} {
proc getLinesFromRange {W range} {
set from [lindex $range 0]
set to [lindex $range 1]
lassign [split $from "."] fromr fromi
lassign [split $to "."] tor toi
if {$toi == 0} {incr tor -1}
# Get the corresponding lines in the file
set t [$w get $fromr.0 $tor.end]
set t [$W get $fromr.0 $tor.end]
set lines [lsort -integer [regexp -all -inline {\d+} $t]]
set froml [lindex $lines 0]
set tol [lindex $lines end]
return [list $fromr $tor $froml $tol]
}
# Called by popup menus over row numbers to add commands for editing.
# Returns 1 if nothing was added.
proc editMenu {m top side changeIndex x y} {
proc editMenu {mW top side changeIndex x y} {
if {![mayEdit $top $side]} {return 1}
if { ! [mayEdit $top $side]} {return 1}
# Only copy when in a change block
if {$changeIndex ne ""} {
set other [expr {$side == 1 ? 2 : 1}]
set editOther [mayEdit $top $other]
set w $::widgets($top,wLine$side)
set wo $::widgets($top,wLine$other)
set W $::widgets($top,wLine$side)
set oW $::widgets($top,wLine$other)
# Get the row that was clicked
set index [$w index @$x,$y]
set index [$W index @$x,$y]
set row [lindex [split $index "."] 0]
set line [regexp -inline {\d+} [$w get $row.0 $row.end]]
set lineo [regexp -inline {\d+} [$wo get $row.0 $row.end]]
set line [regexp -inline {\d+} [$W get $row.0 $row.end]]
set lineo [regexp -inline {\d+} [$oW get $row.0 $row.end]]
# Row copy
if {$lineo ne ""} {
$m add command -label "Copy Row from other side" \
$mW add command -label "Copy Row from other side" \
-command [list copyRow $top $other $row]
} else {
$m add command -label "Delete Row" \
$mW add command -label "Delete Row" \
-command [list deleteBlock $top $side $row]
}
if {$line ne "" && $editOther} {
$m add command -label "Copy Row to other side" \
$mW add command -label "Copy Row to other side" \
-command [list copyRow $top $side $row]
}
# Get ranges for the change block
set range [$w tag ranges hl$changeIndex]
set rangeo [$wo tag ranges hl$changeIndex]
set range [$W tag ranges hl$changeIndex]
set rangeo [$oW tag ranges hl$changeIndex]
# Get the lines involved in the block
lassign [getLinesFromRange $w $range ] from to froml tol
lassign [getLinesFromRange $wo $rangeo] fromo too fromlo tolo
lassign [getLinesFromRange $W $range ] from to froml tol
lassign [getLinesFromRange $oW $rangeo] fromo too fromlo tolo
# More than one line in the block?
set thisSize 0
set otherSize 0
if {$froml ne "" && $tol ne ""} {
set thisSize [expr {$tol - $froml + 1}]
}
if {$fromlo ne "" && $tolo ne ""} {
set otherSize [expr {$tolo - $fromlo + 1}]
}
if {$thisSize > 1 || $otherSize > 1} {
if {$otherSize > 0} {
$m add command -label "Copy Block from other side" \
$mW add command -label "Copy Block from other side" \
-command [list copyBlock $top $other $fromo $too]
} else {
$m add command -label "Delete Block" \
$mW add command -label "Delete Block" \
-command [list deleteBlock $top $side $from $to]
}
if {$editOther && $thisSize > 0} {
$m add command -label "Copy Block to other side" \
$mW add command -label "Copy Block to other side" \
-command [list copyBlock $top $side $from $to]
}
}
}
$m add command -label "Save File" -command [list saveFile $top $side]
$m add command -label "Save File, Reload" -command [list saveFileR $top $side]
$mW add command -label "Save File" -command [list saveFile $top $side]
$mW add command -label "Save File, Reload" -command [list saveFileR $top $side]
return 0
}
proc saveFile {top side} {
if {$side == 1} {
if {!$::eskil($top,leftEdit)} return
if { ! $::eskil($top,leftEdit)} return
set fileName $::eskil($top,leftFile)
set trans $::eskil($top,lefttranslation)
} else {
if {!$::eskil($top,rightEdit)} return
if { ! $::eskil($top,rightEdit)} return
set fileName $::eskil($top,rightFile)
set trans $::eskil($top,righttranslation)
}
set w $::widgets($top,wDiff$side)
set W $::widgets($top,wDiff$side)
# Confirm dialog
set apa no
if {$::Pref(askOverwrite)} {
set apa [tk_messageBox -parent $top -icon question \
-title "Overwrite file" -type yesnocancel -message \
"Overwriting file [file tail $fileName]\nDo you want to\
|
︙ | | |
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
|
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
|
-
+
|
}
set ch [open $fileName "w"]
if {$trans ne ""} {
fconfigure $ch -translation $trans
}
set save 1
foreach {key value index} [$w dump -all 1.0 end-1c] {
foreach {key value index} [$W dump -all 1.0 end-1c] {
switch -- $key {
text {
if {$save} {
puts -nonewline $ch $value
}
}
tagon {
|
︙ | | |
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
|
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
|
-
-
+
+
|
# Check if a filename is a directory and handle starkits
proc FileIsDirectory {file {kitcheck 0}} {
# Skip directories
if {[file isdirectory $file]} {return 1}
# This detects .kit but how to detect starpacks?
if {[file extension $file] eq ".kit" || $kitcheck} {
if {![catch {package require vfs::mk4}]} {
if {![catch {vfs::mk4::Mount $file $file -readonly}]} {
if { ! [catch {package require vfs::mk4}]} {
if { ! [catch {vfs::mk4::Mount $file $file -readonly}]} {
# Check for contents to ensure it is a kit
if {[llength [glob -nocomplain $file/*]] == 0} {
vfs::unmount $file
}
}
# Now it is possible that the isdirectory status has changed
return [file isdirectory $file]
|
︙ | | |
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
|
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
|
-
+
-
+
-
+
|
}
# When in a vfs, make sure the Tcl file dialog is used
# to be able to access the files in a starkit.
if {$isVfs} {
# Only do this if tk_getOpenFile is not a proc.
if {[info procs tk_getOpenFile] eq ""} {
# If there is any problem, call the real one
if {![catch {set res [::tk::dialog::file:: open {*}$args]}]} {
if { ! [catch {set res [::tk::dialog::file:: open {*}$args]}]} {
return $res
}
}
}
return [tk_getOpenFile {*}$args]
}
proc doOpenLeft {top {forget 0}} {
if {!$forget && [info exists ::eskil($top,leftDir)]} {
if { ! $forget && [info exists ::eskil($top,leftDir)]} {
set initDir $::eskil($top,leftDir)
} elseif {[info exists ::eskil($top,rightDir)]} {
set initDir $::eskil($top,rightDir)
} else {
set initDir [pwd]
}
set apa [myOpenFile -title "Select left file" -initialdir $initDir \
-parent $top]
if {$apa != ""} {
set ::eskil($top,leftDir) [file dirname $apa]
set ::eskil($top,leftFile) $apa
set ::eskil($top,leftLabel) $apa
set ::eskil($top,leftOK) 1
return 1
}
return 0
}
proc doOpenRight {top {forget 0}} {
if {!$forget && [info exists ::eskil($top,rightDir)]} {
if { ! $forget && [info exists ::eskil($top,rightDir)]} {
set initDir $::eskil($top,rightDir)
} elseif {[info exists ::eskil($top,leftDir)]} {
set initDir $::eskil($top,leftDir)
} else {
set initDir [pwd]
}
|
︙ | | |
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
|
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
|
-
+
|
# Dropping two files mean set both
if {[llength $files] >= 2} {
set leftFile [lindex $files 0]
set rightFile [lindex $files 1]
} else {
if {$side eq "any"} {
# Dropped outside the text widgets. Try to be clever.
if {![info exists ::eskil($top,lastDrop)]} {
if { ! [info exists ::eskil($top,lastDrop)]} {
set side left
} elseif {$::eskil($top,lastDrop) eq "left"} {
set side right
} else {
set side left
}
}
|
︙ | | |
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
|
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
|
-
+
-
-
+
+
-
-
-
-
+
+
+
+
-
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
-
+
+
-
+
-
+
-
+
-
+
-
+
|
#####################################
# GUI stuff
#####################################
# A little helper to make a window with scrollbars
# It returns the name of the scrolled window
proc Scroll {dir class w args} {
proc Scroll {dir class W args} {
switch -- $dir {
both {
set scrollx 1
set scrolly 1
}
x {
set scrollx 1
set scrolly 0
}
y {
set scrollx 0
set scrolly 1
}
default {
return -code error "Bad scrolldirection \"$dir\""
}
}
ttk::frame $w
$class $w.s {*}$args
ttk::frame $W
$class $W.s {*}$args
# Move border properties to frame
set bw [$w.s cget -borderwidth]
set relief [$w.s cget -relief]
$w configure -relief $relief -borderwidth $bw
$w.s configure -borderwidth 0
set bw [$W.s cget -borderwidth]
set relief [$W.s cget -relief]
$W configure -relief $relief -borderwidth $bw
$W.s configure -borderwidth 0
grid $w.s -sticky news
grid $W.s -sticky news
if {$scrollx} {
$w.s configure -xscrollcommand [list $w.sbx set]
ttk::scrollbar $w.sbx -orient horizontal -command [list $w.s xview]
grid $w.sbx -row 1 -sticky we
$W.s configure -xscrollcommand [list $W.sbx set]
ttk::scrollbar $W.sbx -orient horizontal -command [list $W.s xview]
grid $W.sbx -row 1 -sticky we
}
if {$scrolly} {
$w.s configure -yscrollcommand [list $w.sby set]
ttk::scrollbar $w.sby -orient vertical -command [list $w.s yview]
grid $w.sby -row 0 -column 1 -sticky ns
$W.s configure -yscrollcommand [list $W.sby set]
ttk::scrollbar $W.sby -orient vertical -command [list $W.s yview]
grid $W.sby -row 0 -column 1 -sticky ns
}
grid columnconfigure $w 0 -weight 1
grid rowconfigure $w 0 -weight 1
grid columnconfigure $W 0 -weight 1
grid rowconfigure $W 0 -weight 1
return $w.s
return $W.s
}
# Rearrange a dynamic grid to a specified number of columns
proc DynGridRearrange {w cols} {
proc DynGridRearrange {W cols} {
# Go down columns first. Thus we must know how many rows there will be.
set children [grid slaves $w._dyn]
set children [grid slaves $W._dyn]
set rows [expr {([llength $children] + $cols - 1) / $cols}]
set row 0
set col 0
foreach child $children {
grid $child -row $row -column $col
grid columnconfigure $w._dyn $col -uniform a
grid columnconfigure $W._dyn $col -uniform a
incr row
if {$row >= $rows} {
incr col
set row 0
}
}
# Clear other columns from uniform in case we shrunk
if {$row != 0} {
incr col
}
for {} {$col < 15} {incr col} {
grid columnconfigure $w._dyn $col -uniform ""
grid columnconfigure $W._dyn $col -uniform ""
}
# Recalculate
update idletasks
# Propagate Height
set height [winfo reqheight $w._dyn]
$w configure -width 100 -height $height
set height [winfo reqheight $W._dyn]
$W configure -width 100 -height $height
}
# Update dynamic grid on configure event
proc DynGridRedo {w} {
proc DynGridRedo {W} {
set maxW 0
set children [grid slaves $w._dyn]
set children [grid slaves $W._dyn]
foreach child $children {
set maxW [expr {max($maxW,[winfo reqwidth $child])}]
}
set fW [winfo width $w]
set fW [winfo width $W]
set cols [expr {max(1,$fW / $maxW)}]
# Rerrange if needed
lassign [grid size $w._dyn] mCols mRows
lassign [grid size $W._dyn] mCols mRows
if {$mCols != $cols} {
DynGridRearrange $w $cols
DynGridRearrange $W $cols
}
}
# Ask for widget to have its children managed by dynGrid.
proc dynGridManage {W} {
# Limit its inital requirements
pack propagate $W 0
|
︙ | | |
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
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
2651
2652
2653
2654
|
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
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
2651
2652
2653
2654
|
-
+
-
+
-
-
+
+
-
+
-
+
-
+
-
+
|
# Mark a line as aligned.
proc markAlign {top side line text} {
set ::eskil($top,align$side) $line
set ::eskil($top,aligntext$side) $text
if {[info exists ::eskil($top,align1)] && [info exists ::eskil($top,align2)]} {
if {![string equal $::eskil($top,aligntext1) $::eskil($top,aligntext2)]} {
if { ! [string equal $::eskil($top,aligntext1) $::eskil($top,aligntext2)]} {
set apa [tk_messageBox -icon question -title "Align" -type yesno \
-message "Those lines are not equal.\nReally align them?"]
if {$apa != "yes"} {
return 0
}
}
lappend ::eskil($top,aligns) $::eskil($top,align1) $::eskil($top,align2)
enableAlign $top
NoMarkAlign $top
return 1
}
return 0
}
# Called by popup menus over row numbers to add command for alignment.
# Returns 1 if nothing was added.
proc alignMenu {m top side x y} {
proc alignMenu {mW top side x y} {
# Get the row that was clicked
set w $::widgets($top,wLine$side)
set index [$w index @$x,$y]
set W $::widgets($top,wLine$side)
set index [$W index @$x,$y]
set row [lindex [split $index "."] 0]
set data [$w get $row.0 $row.end]
set data [$W get $row.0 $row.end]
# Must be a line number
if {![regexp {\d+} $data line]} {
if { ! [regexp {\d+} $data line]} {
return 1
}
set text [$::widgets($top,wDiff$side) get $row.0 $row.end]
set other [expr {$side == 1 ? 2 : 1}]
set cmd [list markAlign $top $side $line $text]
if {![info exists ::eskil($top,align$other)]} {
if { ! [info exists ::eskil($top,align$other)]} {
set label "Mark line for alignment"
} else {
set label "Align with line $::eskil($top,align$other) on other side"
}
if {[info exists ::eskil($top,aligns)]} {
foreach {align1 align2} $::eskil($top,aligns) {
if {$side == 1 && $line == $align1} {
set label "Remove alignment with line $align2"
set cmd [list clearAlign $top $align1]
} elseif {$side == 2 && $line == $align2} {
set label "Remove alignment with line $align1"
set cmd [list clearAlign $top $align1]
}
}
}
$m add command -label $label -command $cmd
$mW add command -label $label -command $cmd
return 0
}
# Set up bindings to allow setting alignment using drag
proc SetupAlignDrag {top left right} {
bind $left <ButtonPress-1> [list startAlignDrag $top 1 %x %y %X %Y]\;break
|
︙ | | |
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
|
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
|
-
-
+
+
-
+
-
+
|
bind $right <ButtonRelease-1> [list endAlignDrag $top 2 %x %y %X %Y]\;break
bind $right <B1-Leave> break
}
# Button has been pressed over line window
proc startAlignDrag {top side x y X Y} {
# Get the row that was clicked
set w $::widgets($top,wLine$side)
set index [$w index @$x,$y]
set W $::widgets($top,wLine$side)
set index [$W index @$x,$y]
set row [lindex [split $index "."] 0]
set data [$w get $row.0 $row.end]
set data [$W get $row.0 $row.end]
set ::eskil($top,alignDrag,state) none
# Must be a line number
if {![regexp {\d+} $data line]} {
if { ! [regexp {\d+} $data line]} {
return 1
}
# Set up information about start of drag
set text [$::widgets($top,wDiff$side) get $row.0 $row.end]
set other [expr {$side == 1 ? 2 : 1}]
set ::eskil($top,alignDrag,X) $X
set ::eskil($top,alignDrag,Y) $Y
|
︙ | | |
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
|
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
|
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
+
-
+
-
+
-
+
|
proc motionAlignDrag {top side shift x y X Y} {
if {$::eskil($top,alignDrag,state) eq "press"} {
# Have we moved enough to call it dragging?
set dX [expr {abs($X - $::eskil($top,alignDrag,X))}]
set dY [expr {abs($Y - $::eskil($top,alignDrag,Y))}]
if {$dX + $dY > 3} {
# Start a drag action
set w $top.alignDrag
destroy $w
toplevel $w
wm overrideredirect $w 1
label $w.l -borderwidth 1 -relief solid -justify left
pack $w.l
set ::eskil($top,alignDrag,W) $w
set W $top.alignDrag
destroy $W
toplevel $W
wm overrideredirect $W 1
label $W.l -borderwidth 1 -relief solid -justify left
pack $W.l
set ::eskil($top,alignDrag,W) $W
set ::eskil($top,alignDrag,state) "drag"
}
}
if {$::eskil($top,alignDrag,state) eq "drag"} {
set w $::eskil($top,alignDrag,W)
set W $::eskil($top,alignDrag,W)
# Move drag label with cursor
wm geometry $w +[expr {$X + 1}]+[expr {$Y + 1}]
wm geometry $W +[expr {$X + 1}]+[expr {$Y + 1}]
set n $::eskil($top,alignDrag,from)
set other [expr {$side == 1 ? 2 : 1}]
set w2 $::widgets($top,wLine$other)
# Are we over the other line window?
if {[winfo containing $X $Y] eq $w2} {
set x [expr {$X - [winfo rootx $w2]}]
set y [expr {$Y - [winfo rooty $w2]}]
set index [$w2 index @$x,$y]
set row [lindex [split $index "."] 0]
set data [$w2 get $row.0 $row.end]
if {![regexp {\d+} $data line]} {
if { ! [regexp {\d+} $data line]} {
set ::eskil($top,alignDrag,line$other) "?"
} else {
set ::eskil($top,alignDrag,line$other) $line
set text [$::widgets($top,wDiff$other) get $row.0 $row.end]
set ::eskil($top,alignDrag,text$other) $text
}
} else {
set ::eskil($top,alignDrag,line$other) "?"
}
set txt "Align Left $::eskil($top,alignDrag,line1)"
append txt "\nwith Right $::eskil($top,alignDrag,line2)"
set ::eskil($top,alignDrag,shift) $shift
if {$shift} {
append txt "\nAnd Redo Diff"
}
$w.l configure -text $txt
$W.l configure -text $txt
}
}
# Button has been released
proc endAlignDrag {top side x y X Y} {
if {$::eskil($top,alignDrag,state) eq "drag"} {
destroy $::eskil($top,alignDrag,W)
|
︙ | | |
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
|
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
|
-
+
-
+
-
-
+
+
-
+
-
+
-
+
|
}
proc hlPopup {top side changeIndex X Y x y} {
if {[info exists ::eskil($top,nopopup)] && $::eskil($top,nopopup)} return
destroy .lpm
menu .lpm
if {![editMenu .lpm $top $side $changeIndex $x $y]} {
if { ! [editMenu .lpm $top $side $changeIndex $x $y]} {
.lpm add separator
}
if {$changeIndex != ""} {
.lpm add command -label "Select" \
-command [list hlSelect $top $changeIndex]
}
set other [expr {$side == 1 ? 2 : 1}]
if {![info exists ::eskil($top,separate$other)]} {
if { ! [info exists ::eskil($top,separate$other)]} {
set label "Mark for Separate Diff"
} else {
set label "Separate Diff"
}
.lpm add command -label $label -command [list hlSeparate $top $side $changeIndex]
alignMenu .lpm $top $side $x $y
set ::eskil($top,nopopup) 1
tk_popup .lpm $X $Y
after idle [list after 1 [list set "::eskil($top,nopopup)" 0]]
return
}
# This is called when right clicking over the line numbers which are not
# marked for changes
proc rowPopup {w X Y x y} {
set top [winfo toplevel $w]
proc rowPopup {W X Y x y} {
set top [winfo toplevel $W]
if {[info exists ::eskil($top,nopopup)] && $::eskil($top,nopopup)} return
destroy .lpm
menu .lpm
regexp {(\d+)\D*$} $w -> side
regexp {(\d+)\D*$} $W -> side
set tmp1 [editMenu .lpm $top $side "" $x $y]
if {!$tmp1} {.lpm add separator}
if { ! $tmp1} {.lpm add separator}
set tmp2 [alignMenu .lpm $top $side $x $y]
if {$tmp1 && $tmp2} {
# Nothing in the menu
return
}
if {!$tmp1 && $tmp2} {.lpm delete last}
if { ! $tmp1 && $tmp2} {.lpm delete last}
set ::eskil($top,nopopup) 1
tk_popup .lpm $X $Y
after idle [list after 1 [list set "::eskil($top,nopopup)" 0]]
}
proc nextHighlight {top} {
|
︙ | | |
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
|
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
|
-
-
+
+
-
+
-
-
+
+
|
incr ::HighLightCount
}
#########
# Zooming
#########
proc zoomRow {w X Y x y} {
set top [winfo toplevel $w]
proc zoomRow {W X Y x y} {
set top [winfo toplevel $W]
# Get the row that was clicked
set index [$w index @$x,$y]
set index [$W index @$x,$y]
set row [lindex [split $index "."] 0]
# Check if it is selected
if {[lsearch [$w tag names $index] sel] >= 0} {
regexp {(\d+)\D*$} $w -> side
if {[lsearch [$W tag names $index] sel] >= 0} {
regexp {(\d+)\D*$} $W -> side
hlPopup $top $side "" $X $Y $x $y
return
}
# Extract the data
set data(1) [$::widgets($top,wDiff1) dump -tag -text $row.0 $row.end]
set data(2) [$::widgets($top,wDiff2) dump -tag -text $row.0 $row.end]
|
︙ | | |
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
|
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
|
-
-
+
+
-
-
+
+
-
+
-
+
-
+
-
+
|
[winfo screenwidth $top]x[winfo reqheight $top.balloon]
set wx 0
}
wm geometry $top.balloon +$wx+$wy
wm deiconify $top.balloon
}
proc unzoomRow {w} {
set top [winfo toplevel $w]
proc unzoomRow {W} {
set top [winfo toplevel $W]
destroy $top.balloon
}
# Reconfigure font
proc chFont {} {
font configure myfont -size $::Pref(fontsize) -family $::Pref(fontfamily)
}
# Change color settings
proc applyColor {} {
global dirdiff
foreach top $::eskil(diffWindows) {
if {$top eq ".clipdiff"} continue
if {[string match .fourway* $top]} continue
if {$top != ".dirdiff"} {
foreach item {wLine1 wDiff1 wLine2 wDiff2} {
if {![info exists ::widgets($top,$item)]} continue
set w $::widgets($top,$item)
if { ! [info exists ::widgets($top,$item)]} continue
set W $::widgets($top,$item)
$w tag configure equal -foreground $::Pref(colorequal) \
$W tag configure equal -foreground $::Pref(colorequal) \
-background $::Pref(bgequal)
$w tag configure new1 -foreground $::Pref(colornew1) \
$W tag configure new1 -foreground $::Pref(colornew1) \
-background $::Pref(bgnew1)
$w tag configure change -foreground $::Pref(colorchange) \
$W tag configure change -foreground $::Pref(colorchange) \
-background $::Pref(bgchange)
$w tag configure new2 -foreground $::Pref(colornew2) \
$W tag configure new2 -foreground $::Pref(colornew2) \
-background $::Pref(bgnew2)
}
continue
}
}
}
|
︙ | | |
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
|
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
|
-
-
-
+
+
+
-
+
-
+
|
}
}
# Emulate a label that:
# 1 : Displays the right part of the text if there isn't enough room
# 2 : Justfify text to the left if there is enough room.
# 3 : Does not try to allocate space according to its contents
proc fileLabel {w args} {
ttk::entryX $w -style TLabel
$w configure {*}$args
proc fileLabel {W args} {
ttk::entryX $W -style TLabel
$W configure {*}$args
$w configure -takefocus 0 -state readonly ;#-readonlybackground $bg
$W configure -takefocus 0 -state readonly ;#-readonlybackground $bg
set i [lsearch $args -textvariable]
if {$i >= 0} {
set var [lindex $args [+ $i 1]]
uplevel \#0 "trace variable $var w \
{after idle {$w xview end} ;#}"
{after idle {$W xview end} ;#}"
}
}
# Fill in default data for a diff window
proc initDiffData {top} {
set ::eskil($top,leftOK) 0
set ::eskil($top,rightOK) 0
|
︙ | | |
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
|
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
|
-
-
+
+
|
wm deiconify $top
raise $top
update
doDiff $top
}
# A thing to easily get to debug mode
proc backDoor {top a} {
append ::eskil(backdoor) $a
proc backDoor {top aVal} {
append ::eskil(backdoor) $aVal
set ::eskil(backdoor) [string range $::eskil(backdoor) end-9 end]
if {$::eskil(backdoor) eq "EskilDebug"} {
set ::eskil(debug) 1
catch {console show}
set ::eskil(backdoor) ""
AddDebugMenu $top
}
|
︙ | | |
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
|
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
|
-
+
|
wm title $top "Eskil:"
wm protocol $top WM_DELETE_WINDOW [list cleanupAndExit $top]
ttk::frame $top.f
grid $top.f -row 0 -columnspan 5 -sticky nws
lappend ::widgets(toolbars) $top.f
if {!$::Pref(toolbar)} {
if { ! $::Pref(toolbar)} {
grid remove $top.f
}
menu $top.m
$top configure -menu $top.m
$top.m add cascade -label "File" -underline 0 -menu $top.m.mf
|
︙ | | |
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
|
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
|
-
+
|
-command [list highlightTabs $top]
set ::widgets($top,enableAlignCmd) [list \
$top.m.mt entryconfigure "Clear Align" -state normal]
set ::widgets($top,disableAlignCmd) [list \
$top.m.mt entryconfigure "Clear Align" -state disabled]
if {$::tcl_platform(platform) eq "windows"} {
if {![catch {package require registry}]} {
if { ! [catch {package require registry}]} {
$top.m.mt add separator
$top.m.mt add command -label "Setup Registry" -underline 6 \
-command makeRegistryWin
}
}
$top.m add cascade -label "Help" -underline 0 -menu $top.m.help
|
︙ | | |
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
|
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
|
-
+
|
# Set up a tag for incremental search bindings
if {[info procs textSearch::enableSearch] != ""} {
textSearch::enableSearch $top.ft1.tt -label ::widgets($top,isearchLabel)
textSearch::enableSearch $top.ft2.tt -label ::widgets($top,isearchLabel)
}
# Set up file dropping in text windows if TkDnd is available
if {![catch {package require tkdnd}]} {
if { ! [catch {package require tkdnd}]} {
dnd bindtarget $top text/uri-list <Drop> "fileDrop $top any %D"
dnd bindtarget $top.ft1.tl text/uri-list <Drop> "fileDrop $top left %D"
dnd bindtarget $top.ft1.tt text/uri-list <Drop> "fileDrop $top left %D"
dnd bindtarget $top.ft2.tl text/uri-list <Drop> "fileDrop $top right %D"
dnd bindtarget $top.ft2.tt text/uri-list <Drop> "fileDrop $top right %D"
}
|
︙ | | |
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
|
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
|
-
+
-
+
-
+
-
-
-
+
+
+
-
-
-
+
+
+
|
text $top.tb -width 4 -wrap none -background $bg \
-font myfont -borderwidth 0 -padx 0 -highlightthickness 0 \
-takefocus 0
commonYScroll $top.sby $top.ft1.tl $top.ft1.tt $top.ft2.tl $top.ft2.tt \
;#$top.tb
applyColor
foreach w [list $top.ft1.tt $top.ft2.tt] {
foreach W [list $top.ft1.tt $top.ft2.tt] {
# The last change in a row is underlined
$w tag configure last -underline 1
$W tag configure last -underline 1
# Each file in a patch view starts with a block of this type
$w tag configure patch -background gray
$W tag configure patch -background gray
# Make sure selection is visible
$w tag raise sel
bind $w <ButtonPress-3> "zoomRow %W %X %Y %x %y"
bind $w <ButtonRelease-3> "unzoomRow %W"
$W tag raise sel
bind $W <ButtonPress-3> "zoomRow %W %X %Y %x %y"
bind $W <ButtonRelease-3> "unzoomRow %W"
}
foreach w [list $top.ft1.tl $top.ft2.tl] {
$w tag configure align -underline 1
bind $w <ButtonPress-3> "rowPopup %W %X %Y %x %y"
foreach W [list $top.ft1.tl $top.ft2.tl] {
$W tag configure align -underline 1
bind $W <ButtonPress-3> "rowPopup %W %X %Y %x %y"
}
SetupAlignDrag $top $top.ft1.tl $top.ft2.tl
grid $top.l1 $top.le - - $top.l2 -row 1 -sticky news
grid $top.ft1 $top.tb $map $top.sby $top.ft2 -row 2 -sticky news
grid $top.sbx1 $top.ls - - $top.sbx2 -row 3 -sticky news
grid columnconfigure $top "$top.ft1 $top.ft2" -weight 1
|
︙ | | |
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
|
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
|
-
+
|
resetEdit $top
return $top
}
proc ValidateNewColors {} {
foreach item {colorchange bgchange colornew1 bgnew1
colornew2 bgnew2 colorequal bgequal} {
if {![info exists ::TmpPref($item)]} continue
if { ! [info exists ::TmpPref($item)]} continue
set col $::TmpPref($item)
if {$col eq ""} continue
if {[catch {winfo rgb . $col}]} {
# FIXA: Error message
# Just restore for now
set ::TmpPref($item) $::Pref($item)
}
|
︙ | | |
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
|
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
|
-
+
-
+
-
+
|
ttk::labelframe .fo.ls -text "Size" -padding 3
spinbox .fo.ls.sp -from 1 -to 30 -increment 1 -width 3 -state readonly \
-textvariable ::TmpPref(fontsize) -command [list exampleFont $lb]
pack .fo.ls.sp -fill both -expand 1
ttk::label .fo.le -text "Example\n0Ooi1Il" -anchor w -font tmpfont \
-width 1 -justify left
if {![info exists ::eskil(fixedfont)]} {set ::eskil(fixedfont) 1}
if { ! [info exists ::eskil(fixedfont)]} {set ::eskil(fixedfont) 1}
ttk::checkbutton .fo.cb -text "Fixed" -variable ::eskil(fixedfont) \
-command [list UpdateFontBox $lb]
ttk::button .fo.bo -text "Ok" -command "applyFont $lb ; destroy .fo"
ttk::button .fo.ba -text "Apply" -command "applyFont $lb"
ttk::button .fo.bc -text "Close" -command "destroy .fo"
if {![info exists FontCache]} {
if { ! [info exists FontCache]} {
set fam [lsort -dictionary [font families]]
font create testfont
foreach f $fam {
if {![string equal $f ""]} {
if { ! [string equal $f ""]} {
font configure testfont -family $f
lappend FontCache $f [font metrics testfont -fixed]
}
}
font delete testfont
}
UpdateFontBox $lb
|
︙ | | |