#----------------------------------------------------------------------
# Eskil, Fourway diff section
#
# Copyright (c) 2018, Peter Spjuth (peter.spjuth@gmail.com)
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
#
#----------------------------------------------------------------------
# $Revision$
#----------------------------------------------------------------------
proc DoFourWayDiff {top} {
# Copy to convenient local vars
foreach field $::eskil(fw,fields) {
set filename($field) $::eskil($top,$field)
set rev($field) $::eskil($top,rev,$field)
}
# Fill in defaults, if revisions are given for empty files
foreach {from to} $::eskil(fw,fields) {
if {$filename($to) eq "" && $rev($to) ne ""} {
set filename($to) $::eskil($top,$from)
}
if {$filename($from) eq "" && $rev($from) ne ""} {
set filename($from) $::eskil($top,$to)
}
}
parray filename
}
# Browse for file
proc DoOpenFw {top field} {
upvar \#0 ::eskil($top,$field) filename
set initDir [pwd]
if {$filename ne ""} {
set initDir [file dirname $filename]
} else {
# Pick default dir from other files
foreach other [lreverse $::eskil(fw,fields)] {
if {$other eq $field} continue
puts $other
if {$::eskil($top,$other) ne ""} {
set initDir [file dirname $::eskil($top,$other)]
puts $initDir
break
}
}
}
set apa [myOpenFile -title "Select file" -initialdir $initDir \
-parent $top]
if {$apa != ""} {
set filename $apa
}
}
# File drop using TkDnd
proc fileDropFw {top field files} {
if {$field eq "any"} {
# Dropped outside the entry widgets. Try to be clever.
set todo {}
# Drop in empty fields first
foreach field $::eskil(fw,fields) {
if {$::eskil($top,$field) eq ""} {
lappend todo $field
}
}
# Fill fields otherwise
if {[llength $todo] == 0} {
set todo $::eskil(fw,fields)
}
} else {
set todo [list $field]
}
foreach fn $files field $todo {
# Loop until any list ends
if {$fn eq "" || $field eq ""} break
# Sanity check
if {[file exists $fn]} {
set ::eskil($top,$field) $fn
}
}
}
proc makeFourWayWin {} {
set top .fourway
if {[winfo exists $top] && [winfo toplevel $top] eq $top} {
raise $top
focus -force $top
return $top
}
destroy $top
toplevel $top -padx 3 -pady 3
eskilRegisterToplevel $top
wm title $top "Four Way Diff"
wm protocol $top WM_DELETE_WINDOW "cleanupAndExit $top"
menu $top.m
$top configure -menu $top.m
$top.m add cascade -menu $top.m.mf -label "File" -underline 0
menu $top.m.mf
$top.m.mf add command -label "Close" -underline 0 \
-command [list cleanupAndExit $top]
$top.m.mf add separator
$top.m.mf add command -label "Quit" -underline 0 \
-command [list cleanupAndExit all]
# Four files, with optional revision
set ::eskil(fw,fields) {base1 change1 base2 change2}
ttk::label $top.l1 -text "Base 1"
ttk::label $top.l2 -text "Changed 1"
ttk::label $top.l3 -text "Base 2"
ttk::label $top.l4 -text "Changed 2"
set txt1 "First diff is made from Base 1 to Changed 1.\n If a file is empty\
and have a revision, the other file name is used."
addBalloon $top.l1 $txt1
addBalloon $top.l2 $txt1
set txt2 [string map {1 2 First Second} $txt1]
addBalloon $top.l3 $txt2
addBalloon $top.l4 $txt2
ttk::label $top.el -text "File path"
ttk::label $top.rl -text "Rev"
addBalloon $top.rl "If you want to use a revisioned controlled file instead\n of\
the one on disk, add a revision here. E.g. 0 can be used\n for\
latest commited revision."
set n 0
foreach field $::eskil(fw,fields) {
incr n
ttk::entryX $top.e$n -width 60 -textvariable ::eskil($top,$field)
ttk::button $top.b$n -text "Browse" -command [list DoOpenFw $top $field]
ttk::entryX $top.r$n -width 6 -textvariable ::eskil($top,rev,$field)
}
ttk::button $top.bd -text "Diff" -command "DoFourWayDiff $top" -underline 0 \
-width 8
bind $top <Alt-d> [list $top.bd invoke]
grid x $top.el x $top.rl -sticky w -padx 3 -pady 3
grid $top.l1 $top.e1 $top.b1 $top.r1 -sticky we -padx 3 -pady 3
grid $top.l2 $top.e2 $top.b2 $top.r2 -sticky we -padx 3 -pady 3
grid $top.l3 $top.e3 $top.b3 $top.r3 -sticky we -padx 3 -pady {10 3}
grid $top.l4 $top.e4 $top.b4 $top.r4 -sticky we -padx 3 -pady 3
grid $top.bd - - -padx 3 -pady {10 3}
# Set up file dropping in entry windows if TkDnd is available
if {![catch {package require tkdnd}]} {
dnd bindtarget $top text/uri-list <Drop> "fileDropFw $top any %D"
dnd bindtarget $top.e1 text/uri-list <Drop> "fileDropFw $top base1 %D"
dnd bindtarget $top.e2 text/uri-list <Drop> "fileDropFw $top change1 %D"
dnd bindtarget $top.e3 text/uri-list <Drop> "fileDropFw $top base2 %D"
dnd bindtarget $top.e4 text/uri-list <Drop> "fileDropFw $top change2 %D"
}
return $top
}