#!/usr/local/bin/wish

### this section is configured by the Makefile
set TkGnats(lib) ./; ##TKGNATSLIB##
###

foreach f { tkpr_library.tcl tkprhelp.tcl } {
    source $TkGnats(lib)/$f
}

##################################################################

proc headingMsg {a {flash 1}} {
    .mframe.msg configure -text $a
    update idletasks
    if {$flash} {
	foreach rep {1 2 3 4 5} {
	    foreach r {raised sunken flat} {
		.mframe.msg configure -relief $r;
		update idletasks
		after 50
	    }
	}
    }
}

proc merge_into_list {lname new_value {omit_value {}}} {
    upvar 1 $lname l
    set omit_addr [lindex [extract_email_address $omit_value] 0]
    # set omit_name [lindex [extract_email_address $omit_value] 1]
    set adds  [split $new_value ,]
    set nadds [llength $adds]
    for {set i 0} {$i < $nadds} {incr i} {
        set add      [string trim [lindex $adds $i]]
        set new_addr [lindex [extract_email_address $add] 0]
        # set new_name [lindex [extract_email_address $add] 1]
        if {"$new_addr" != "$omit_addr"} {
            if {[lsearch $l $new_addr] < 0} {
                lappend l $new_addr
            }
        }
    }
}

proc file_report {} {
    if {[real_file_report] == -1} {
        bell
	headingMsg "Error filing report!"
	headingMsg "" 0
	return -1
    }
    return 0
}

proc real_file_report {} {
    global Tkeditpr TkGnats frm flds errorCode
    flush_singletext $Tkeditpr(singletextflds)
    flush_multitext

    #
    # do some local field checking..
    #
    headingMsg "Checking fields.." 0
    # - Check Category field...
    if {[lsearch -exact $Tkeditpr(cats) $frm(>Category)] < 0} {
        Msg "You have specified an invalid Category!"
        return -1
    }
    # - Check Submitter field...
    if {[lsearch -exact $Tkeditpr(subs) $frm(>Submitter-Id)] < 0} {
        Msg "You have specified an invalid Submitter-Id!"
        return -1
    }
    # - Check Responsible field...
    if {[lsearch -exact $Tkeditpr(ress) $frm(>Responsible)] < 0} {
        Msg "You have specified an invalid Responsible!"
        return -1
    }
##### This isn't necessary.
#    if {"[get_passwd_entry $frm(>Responsible)]" == ""} {
#	Msg "'$frm(>Responsible)' is not a valid user!"
#	return -1
#    }
    # - Check that indexed text fields do not have a | char. (hoses tkquerypr)
    foreach t {>Release >Synopsis} {
	if {[string first "|" [textget $t]] != -1} {
            Msg " '|' is an illegal character for the '$t' field!"
            return -1
	}
    }
    foreach t {>Environment} {
	if {[string first "|" $frm($t)] != -1} {
            Msg " '|' is an illegal character for the '$t' field!"
            return -1
	}
    }

    #
    # now see if any fields changed that trigger notifiers or audit records
    #
    # >Synopsis
    set mail_list ""
    set all_changes ""
    set datestr [clock format [clock seconds]]

    set responsible_code     [catch {my_pr_addr $frm(>Responsible)}  responsible_addr]
    set old_responsible_code [catch {my_pr_addr $flds(>Responsible)} old_responsible_addr]

    if {$responsible_code} {
	set err "Could not verify E-mail address of new responsible party."
	append err "Address used: $frm(>Responsible)\n"
	append err "Resulting error(s):\n\n$responsible_addr\n"
	set responsible_addr ""
	Msg $err
	return -1
    }
 
    if {$old_responsible_code} {
	Msg "Warning: Could not verify E-mail address of old responsible party.\n" \
                "Address used: $flds(>Responsible)\n" \
                "Resulting error(s):\n\n$old_responsible_addr"
	set old_responsible_addr ""
    }
 
    set t ">Responsible"
    if {$frm($t) != $flds($t)} {

	# if we got the old_responsible persons address OK then mail to them
	if { "$old_responsible_code" != "" } {
	    merge_into_list mail_list $old_responsible_addr $TkGnats(EmailAddr)
	}
	# if the new responsible person is not us then mail to them
        merge_into_list mail_list $responsible_addr $TkGnats(EmailAddr)

	set change_msg "\n\nResponsible-Changed-From-To: $flds($t)->$frm($t)\n"
	append change_msg  "Responsible-Changed-By:      $TkGnats(LogName)\n"
	append change_msg  "Responsible-Changed-When:    $datestr\n"
	set whyText ""
	catch {
	    set whyText [entryDialog "Enter reason for Responsible change" no_cancel]
	}
	append change_msg  "Responsible-Changed-Why:     $whyText\n"

	append all_changes $change_msg 
    }
 
    set t ">State"
    if {$frm($t) != $flds($t)} {

	set change_msg	"\n\nState-Changed-From-To: $flds($t)-$frm($t)\n"
	append change_msg   "State-Changed-By:      $TkGnats(LogName)\n"
	append change_msg   "State-Changed-When:    $datestr\n"
	set whyText ""
	catch {
	    set whyText [entryDialog "Enter reason for state change" no_cancel]
	}
	append change_msg   "State-Changed-Why:     $whyText\n"

	append all_changes $change_msg 

	# if the new responsible person is not us then mail to them the status change
        merge_into_list mail_list $responsible_addr $TkGnats(EmailAddr)
    }

    #
    # did any notifiable changes take place ??
    #
    if {"$all_changes" != ""} {

        # Send to the original sender and the Reply-To list, but omit us
        merge_into_list mail_list $flds(From)    $TkGnats(EmailAddr)
        merge_into_list mail_list $frm(Reply-To) $TkGnats(EmailAddr)
##puts "maillist=$mail_list"        
        if {"$mail_list" != ""} {
            set   stamp  $TkGnats(LogName)[clock format [clock seconds] -format "%j:%T"]
            set   tmpfilename /tmp/tksendpr.$stamp
            set   fout [open $tmpfilename "w"]
            ## set fout [open "|$TkGnats(Mailer)" w]
            puts  $fout "To: [join $mail_list ", "]"
##puts "maillist=[join $mail_list ", "]" 
            puts  $fout "From: $TkGnats(EmailAddr)"
            puts  $fout "Reply-To: $TkGnats(EmailAddr)"
            puts  $fout "Subject: Changed information for PR $frm(>Category)/$Tkeditpr(prid)"
            puts  $fout "\n\nSynopsis: $frm(>Synopsis)"
            puts  $fout $all_changes nonewline
            close $fout
            set code [catch {eval exec $TkGnats(Mailer) < $tmpfilename} result]
            file delete $tmpfilename
        }
	append frm(>Audit-Trail) $all_changes
    }
    headingMsg "Filing report.." 0

    set stamp  $TkGnats(LogName)[clock format [clock seconds] -format "%j:%T"]
    set tmpfile /tmp/tksendpr.$stamp
    set fout [open $tmpfile "w"]
    write_pr $fout
    close $fout

    set errs ""
    set x [catch "exec $TkGnats(pr-edit) --check < $tmpfile" errs]
    ## "$errs" != ""
    if {0}  {
	Msg "Error checking $tmpfile:\n" "$errs\n" "$errorCode"
    } else {
	if {[catch "exec $TkGnats(pr-edit) < $tmpfile" errs]} {
	    Msg "Error filing $tmpfile:\n" "$errs"
	} else {
	    headingMsg "Done" 0
	    file delete $tmpfile
	    # Exit 0
            destroy .
	}
    }
    file delete $tmpfile
    destroy .
    # return -1
}

proc write_multitextfld {fout flds tag} {
    upvar 1 $flds f
    puts $fout [string trimleft "$tag: \n[string trim $f($tag) "\n"]" "\n"]
}

proc write_pr {fout} {
    global Tkeditpr flds frm

    foreach tag [array names frm] {
	set still_left($tag) $tag
    }

    #
    # for each parsed field from the PR form...
    #
    foreach tag $Tkeditpr(parsed_flds) {
	case $tag {_prefix_} {
	    #
	    #	The mail header, stored under the _prefix_ tag, is written out
	    #	unadulterated, except for the edited Reply-To field.
	    #
            set lines [split $flds($tag) \n]
            set repin [lsearch -regexp $lines "^Reply-To: "]
            set repto "Reply-To: $frm(Reply-To)"
            set newlines [lreplace $lines $repin $repin $repto]
            set frm($tag) [join $newlines \n]
	    puts $fout $frm($tag) nonewline
	} {Reply-To} {
	    #
	    # Taken care of above with the mail header
	    #
            unset still_left($tag)
	} {>Unformatted} {
	    #
	    # Taken care of later in the function...
	    #
            unset still_left($tag)
	} {>*} {
	    # When writing out the fields
	    #	first check for data present in the form (the frm bag)
	    #	If not present use data read from the PR file (the flds bag)
	    #
	    if {[info exists frm($tag)]} {
		set data $frm($tag)
		unset still_left($tag)
	    } else {
		set data $flds($tag)
	    }

	    #
	    # Write out fields
	    #
	    #	Multi line fields are newline trimmed to a single leading
	    #	and trailing newline
	    #
	    #	Single line text fields are whitespace trimmed to a leading
	    #	tab and a trailing newline
	    #
	    case $tag $Tkeditpr(singletextflds) {
                if {$tag != "Reply-To"} {
                    puts $fout "$tag:\t[string trim [textget $tag] "\t\n "]"
                }
	    } [concat >Category >Responsible >Submitter-Id $Tkeditpr(radioflds)] {
		puts $fout "$tag:\t$frm($tag)"
	    } $Tkeditpr(multitextflds) {
		write_multitextfld $fout frm $tag
	    } default {
		puts $fout "$tag:$data" nonewline
	    }
	}
    }

    #
    # now write any fields in the form that were not in the parsed report
    #
    foreach tag [array names still_left] {
	write_multitextfld $fout frm $tag
    }

    #
    # Finally, write the >Unformatted field
    #   (BUG: >Unformatted should not really be stripped)
    #
    write_multitextfld $fout frm ">Unformatted"
}

proc cancel_report {} {
    # Exit 0
    destroy .
}

proc edit_category_listbox {p {pat *} {valwid 0}} {
    global flds frm Tkeditpr
    set Tkeditpr(cats) [get_categories $pat]
    if {$valwid == 0} {
        set valwid [string length [ftrim $flds(>Category)]]
    }

    set wid [expr 2 + [get_max_strlen $Tkeditpr(cats)]]
    set Tkeditpr(listbox_width) $wid
    
    frame  $p.cat -relief flat
    pack   $p.cat -side top -anchor w
    button $p.cat.lab -text "Category: " -width 14 -anchor w -command "helpMsg Category" \
            -relief flat -padx 0 -pady 0 -borderwidth 0 -highlightthickness 1
    frame  $p.cat.msg -relief flat
    label  $p.cat.msg.val -text "[ftrim $flds(>Category)]" -relief groove -anchor w \
            -width $wid -background green
    set ew [entry $p.cat.msg.ent -width $wid -insertwidth 1 -insertofftime 400 \
            -relief sunken -borderwidth 2 -background grey95 -textvariable frm(>Category)]
    lappend Tkeditpr(tlist) $ew
    bind $ew <Enter> "+focus $ew"
    scrollbar $p.cat.msg.sb -command "$p.cat.msg.list yview" -borderwidth 2 -relief sunken
    set height [llength $Tkeditpr(cats)]
    if {$height > 6 } {
        set height 6
    }
    set Tkeditpr(listbox_height) $height
    listbox $p.cat.msg.list -yscroll "$p.cat.msg.sb set" -setgrid 1 -relief sunken -borderwidth 2 \
            -width $wid -height $height -exportselection false
    pack $p.cat.msg.val  -side top   -fill both -expand true -anchor center
    pack $p.cat.msg.ent  -side top   -fill both -expand true -anchor w
    pack $p.cat.msg.list -side left  -fill both -expand true
    pack $p.cat.msg.sb   -side right -fill y
    eval $p.cat.msg.list insert end $Tkeditpr(cats)
    trace variable frm(>Category) w set_edit_category_ew
    pack $p.cat.lab $p.cat.msg -side left -anchor n
    bind   $p.cat.msg.list <B1-ButtonRelease> "set_edit_category $p.cat.msg %W %y"
    return $p.cat.msg.list
}

proc edit_responsible_listbox {p {pat *} {valwid 0}} {
    global flds frm Tkeditpr
    set Tkeditpr(ress) [get_responsibles $pat]
    if {$valwid == 0} {
        set valwid [string length [ftrim $flds(>Responsible)]]
    }

    set wid [expr 2 + [get_max_strlen $Tkeditpr(ress)]]
    frame  $p.res -relief flat
    pack   $p.res -side top -anchor w
    button $p.res.lab -text "Responsible: " -width 14 -anchor w -command "helpMsg Responsible" \
            -relief flat -padx 0 -pady 0 -borderwidth 0 -highlightthickness 1
    frame  $p.res.msg -relief flat
    label  $p.res.msg.val -text "[ftrim $flds(>Responsible)]" -relief groove -anchor w \
            -width $wid -background green
    set ew [entry $p.res.msg.ent -width $wid -insertwidth 1 -insertofftime 400 \
            -relief sunken -borderwidth 2 -background grey95 -textvariable frm(>Responsible)]
    lappend Tkeditpr(tlist) $ew
    bind $ew <Enter> "+focus $ew"
    scrollbar $p.res.msg.sb -command "$p.res.msg.list yview" -borderwidth 2 -relief sunken
    set height [llength $Tkeditpr(ress)]
    if {$height > 6 } {
        set height 6
    }
    listbox $p.res.msg.list -yscroll "$p.res.msg.sb set" -setgrid 1 -relief sunken \
            -borderwidth 2 -width $wid -height $Tkeditpr(listbox_height) -exportselection false
    pack $p.res.msg.val  -side top   -fill both -expand true -anchor center
    pack $p.res.msg.ent  -side top   -fill both -expand true -anchor w
    pack $p.res.msg.list -side left  -fill both -expand true
    pack $p.res.msg.sb   -side right -fill y
    eval $p.res.msg.list insert end $Tkeditpr(ress)
    trace variable frm(>Responsible) w set_edit_responsible_ew
    pack $p.res.lab $p.res.msg -side left -anchor n
    bind   $p.res.msg.list <B1-ButtonRelease> "set_edit_responsible $p.res.msg %W %y"
    return $p.res.msg.list
}

proc edit_submitter_listbox {p {pat *} {valwid 0}} {
    global flds frm Tkeditpr
    set Tkeditpr(subs) [get_submitters $pat]
    if {$valwid == 0} {
        set valwid [string length [ftrim $flds(>Submitter-Id)]]
    }

    set wid [expr 2 + [get_max_strlen $Tkeditpr(subs)]]
    frame  $p.sub -relief flat
    pack   $p.sub -side top -anchor w
    button $p.sub.lab -text "Submitter-Id: " -width 14 -anchor w -command "helpMsg Submitter-Id" \
            -relief flat -padx 0 -pady 0 -borderwidth 0 -highlightthickness 1
    frame  $p.sub.msg -relief flat
    label  $p.sub.msg.val -text "[ftrim $flds(>Submitter-Id)]" -relief groove -anchor w \
            -width $wid -background green
    set ew [entry $p.sub.msg.ent -width $wid -insertwidth 1 -insertofftime 400 \
            -relief sunken -borderwidth 2 -background grey95 -textvariable frm(>Submitter-Id)]
    lappend Tkeditpr(tlist) $ew
    bind $ew <Enter> "+focus $ew"
    scrollbar $p.sub.msg.sb -command "$p.sub.msg.list yview" -borderwidth 2 -relief sunken
    set height [llength $Tkeditpr(subs)]
    if {$height > 6 } {
        set height 6
    }
    listbox $p.sub.msg.list -yscroll "$p.sub.msg.sb set" -setgrid 1 -relief sunken \
            -borderwidth 2 -width $wid -height $Tkeditpr(listbox_height) -exportselection false
    pack $p.sub.msg.val  -side top   -fill both -expand true -anchor center
    pack $p.sub.msg.ent  -side top   -fill both -expand true -anchor w
    pack $p.sub.msg.list -side left  -fill both -expand true
    pack $p.sub.msg.sb   -side right -fill y
    eval $p.sub.msg.list insert end $Tkeditpr(subs)
    trace variable frm(>Submitter-Id) w set_edit_submitter_ew
    pack $p.sub.lab $p.sub.msg -side left -anchor n
    bind   $p.sub.msg.list <B1-ButtonRelease> "set_edit_submitter $p.sub.msg %W %y"
    return $p.sub.msg.list
}

proc set_edit_category_ew {a b c} {
    upvar #0 $a f
    global Tkeditpr
    quickfill_entry_from_listbox f($b) .eboxs.clb.cat.msg.ent .eboxs.clb.cat.msg.list $Tkeditpr(cats)
}

proc set_edit_submitter_ew {a b c} {
    upvar #0 $a f
    global Tkeditpr
    quickfill_entry_from_listbox f($b) .eboxs.slb.sub.msg.ent .eboxs.slb.sub.msg.list $Tkeditpr(subs)
}

proc set_edit_responsible_ew {a b c} {
    upvar #0 $a f
    global Tkeditpr
    quickfill_entry_from_listbox f($b) .eboxs.rlb.res.msg.ent .eboxs.rlb.res.msg.list $Tkeditpr(ress)
}

proc set_edit_category {msg w y} {
    global frm
    trace vdelete  frm(>Category) w set_edit_category_ew
    $msg.ent delete 0 end
    set idx [$w nearest $y]
    set frm(>Category) [$w get $idx]
    trace variable frm(>Category) w set_edit_category_ew
}

proc set_edit_responsible {msg w y} {
    global frm
    trace vdelete  frm(>Responsible) w set_edit_responsible_ew
    $msg.ent delete 0 end
    set idx [$w nearest $y]
    set frm(>Responsible) [$w get $idx]
    trace variable frm(>Responsible) w set_edit_responsible_ew
}

proc set_edit_submitter {msg w y} {
    global frm
    trace vdelete  frm(>Submitter) w set_edit_submitter_ew
    $msg.ent delete 0 end
    set idx [$w nearest $y]
    set frm(>Submitter-Id) [$w get $idx]
    trace variable frm(>Submitter) w set_edit_submitter_ew
}

proc sanity_check {fields} {
}

proc fillfrm {} {
    global frm flds Tkeditpr

    ### pre-set editable PR values to values currently in the PR

    # clear listbox entry widgets
    .eboxs.clb.cat.msg.ent delete 0 end
    .eboxs.slb.sub.msg.ent delete 0 end
    .eboxs.rlb.res.msg.ent delete 0 end

    # listboxes and radio (enumerated) fields
    foreach tag [concat >Category >Responsible >Submitter-Id $Tkeditpr(radioflds)] {
	set flds($tag) [string trim $flds($tag) "\t\n "]
	set frm($tag) $flds($tag)
    }

    # now the 1 line textual flds
    foreach tag $Tkeditpr(singletextflds) {
	set flds($tag) [string trim $flds($tag) "\t\n "]
	textset $tag $flds($tag)
    }

    # now the multi line textual flds
    foreach tag $Tkeditpr(multitextflds) {
	if {[info exists flds($tag)]} {
	    set $flds($tag) [string trim $flds($tag) "\n"]
	    set frm($tag) $flds($tag)
	} else {
	    set frm($tag)  "\n"
	    set flds($tag) "\n"
	}
    }
    switch_txt ">Description" $Tkeditpr(multitextflds)
}

proc reset_report {} {
    global flds current_multi_text Tkeditpr
    # load the current text widget with the original text
    .multiline.text delete 1.0 end
    .multiline.text insert 1.0 $flds($current_multi_text)
    # reset everything
    set current $current_multi_text
    fillfrm
    switch_txt $current $Tkeditpr(multitextflds)
}

proc edit_window {} {
    global TkGnats Tkeditpr env current_multi_text flds

    set prid $Tkeditpr(prid)
    
    set Tkeditpr(radioflds) {
        >State
        >Confidential
        >Severity
        >Priority
        >Class
    }
    
    set Tkeditpr(singletextflds) {
        >Originator
        Reply-To
        >Release
        >Synopsis
    }

    if {$TkGnats(ReleaseBased)} {
	lappend Tkeditpr(singletextflds) {>Keywords}
    }
    
    set Tkeditpr(multitextflds) {
        >Description
        >How-To-Repeat
        >Environment
        >Audit-Trail
        >Unformatted
        >Fix
    }
    
    # List of entry widgets for traverse key binding
    set Tkeditpr(tlist) {}
    
    set current_multi_text ""
    
    # load a bunch of defaults into flds.
    
    set fin [open "|query-pr --full [file tail $Tkeditpr(prid)]" r]
    set Tkeditpr(parsed_flds) [parsepr $fin flds]
    set missing_list [load_field_defaults flds]
    close $fin
    
    frame   .mframe     -borderwidth 1 -relief raised
    pack    .mframe     -side top -fill x
    message .mframe.msg -aspect 10000 
    pack    .mframe.msg -side left -fill x
    
    menubutton .mframe.help -text "Help" -menu .mframe.help.m -underline 0
    menu       .mframe.help.m
    .mframe.help.m add command -label "Overview" \
            -command "helpMsg Edit_Overview"
    .mframe.help.m add separator
    .mframe.help.m add command -label "Field Definitions" \
            -command "helpMsg Field_Definitions"
    .mframe.help.m add separator
    .mframe.help.m add command -label "Radio Buttons (Class, etc)" \
            -command "helpMsg Edit_Radio_Buttons"
    .mframe.help.m add command -label "Listbox Selectors (Category, etc)" \
            -command "helpMsg Edit_Listbox_Selectors"
    .mframe.help.m add command -label "Entry Fields (Originator, etc)" \
            -command "helpMsg Edit_Entry_Fields"
    .mframe.help.m add command -label "Text Fields (Description, etc)" \
            -command "helpMsg Edit_Text_Fields"
    .mframe.help.m add separator
    .mframe.help.m add command -label "About" \
            -command "helpMsg TkGnats_Version"
    pack       .mframe.help -side right
    
    # Get the maximum width of the value fields for the bagged_radiobar
    set Tkeditpr(value_width) 0
    foreach tag [concat >Category >Responsible $Tkeditpr(radioflds)] {
        set f [ftrim $flds($tag)]
        if {[string length $f] > $Tkeditpr(value_width)} {
            set Tkeditpr(value_width) [string length $f]
        }
    }
    
    # Get the maximum width of the value fields for the readonly_singletext fields
    ###set Tkeditpr(singletextvalue_width) \
            ###        [string length "[ftrim $flds(>Originator)] (email: $flds(Reply-To))"]
    set Tkeditpr(singletextvalue_width) 0
    foreach tag [concat >Last-Modified >Arrival-Date] {
        set f [ftrim $flds($tag)]
        if {[string length $f] > $Tkeditpr(singletextvalue_width)} {
            set Tkeditpr(singletextvalue_width) [string length $f]
        }
    }
    
    ###readonly_singletext Originator   "[ftrim $flds(>Originator)] (email: $flds(Reply-To))"  14 \
            ###        $Tkeditpr(singletextvalue_width)
    readonly_singletext Arrival-Date  [ftrim $flds(>Arrival-Date)]  14 \
            $Tkeditpr(singletextvalue_width)
    readonly_singletext Last-Modified [ftrim $flds(>Last-Modified)] 14 \
            $Tkeditpr(singletextvalue_width)
    
    frame .eflds
    radiobar_frame .eflds .eflds.lb
    bagged_radiobar .eflds.lb class Class \
            {sw-bug doc-bug change-request support mistaken duplicate} None frm $Tkeditpr(value_width)
    bagged_radiobar .eflds.lb state "State" \
            {open analyzed feedback closed suspended} None frm $Tkeditpr(value_width)
    bagged_radiobar .eflds.lb priority Priority \
            {low medium high} None frm $Tkeditpr(value_width)
    bagged_radiobar .eflds.lb severity Severity \
            {non-critical serious critical} None frm $Tkeditpr(value_width)
    bagged_radiobar .eflds.lb confidential "Confidential" \
            {no yes} None frm $Tkeditpr(value_width)
    pack .eflds.lb -side left -pady 0
    pack .eflds    -side top  -pady 0 -fill x -anchor w
    
    frame .eboxs
    frame .eboxs.clb -relief groove -borderwidth 2
    edit_category_listbox .eboxs.clb * $Tkeditpr(value_width)
    frame .eboxs.slb -relief groove -borderwidth 2
    edit_submitter_listbox   .eboxs.slb * $Tkeditpr(value_width)
    frame .eboxs.rlb -relief groove -borderwidth 2
    edit_responsible_listbox .eboxs.rlb * $Tkeditpr(value_width)
    
    pack .eboxs.clb -side left -anchor w -pady 2 -padx 0
    pack .eboxs.slb -side left -anchor w -pady 2 -padx 4
    pack .eboxs.rlb -side left -anchor w -pady 2 -padx 0
    pack .eboxs -side top -fill x -anchor w -pady 2 -padx 0
    
    lappend Tkeditpr(tlist) [singletext . >Originator  80 "" 14]
    lappend Tkeditpr(tlist) [singletext . Reply-To     80 "" 14]
    lappend Tkeditpr(tlist) [singletext . >Release     80 "" 14]
    lappend Tkeditpr(tlist) [singletext . >Synopsis    80 "" 14]

    if {$TkGnats(ReleaseBased)} {
	lappend Tkeditpr(tlist) [singletext . >Keywords 80 "" 14]
    }
    
    lappend Tkeditpr(tlist) [make_txt_mb $Tkeditpr(multitextflds)]
    
    set_text_traversal $Tkeditpr(tlist)
    
    frame  .action -borderwidth 3
    button .action.send   -borderwidth 2 -text "Save Changes"              -command file_report
    button .action.cancel -borderwidth 2 -text "Cancel"                    -command cancel_report
    button .action.reset  -borderwidth 2 -text "Reset to Starting Values"  -command reset_report
    button .action.email  -borderwidth 2 -text "Send Email..." \
            -command "email_originator [list [ftrim $flds(Reply-To)]] [list [ftrim $flds(>Responsible)]] \
            [list [ftrim $flds(From)]] [ftrim $flds(>Category)]/$prid [list [ftrim $flds(>Synopsis)]]"
    ##    [lrange [split [ftrim $flds(>Originator)]] 0 0]
    
    pack .action.send .action.reset .action.email .action.cancel -side left -padx 8
    pack .action -side top
    
    wm title      . "TkGnats - Edit Problem Report: [ftrim $flds(>Category)]/[ftrim $flds(>Number)]"
    wm iconbitmap . @$TkGnats(lib)/tkeditpr.xbm
    wm iconname   . "$TkGnats(LogName)'s tkeditpr [ftrim $flds(>Number)]"
    fillfrm

    tkwait visibility .
    
    if {"$missing_list" != ""} {
	Msg "The following fields were missing from the report but will be added when you Save Changes:\n" "$missing_list"
	set Tkeditpr(parsed_flds) [concat $Tkeditpr(parsed_flds) $missing_list]
    }
}

##################################################################

set  numerrs 0

set  Tkeditpr(prid) [lindex $argv 0]
if {$Tkeditpr(prid) == ""} {
    wm withdraw .
    Msg "No problem report id supplied!\n" "Usage:  tkeditpr  prid"
    incr numerrs
}

if {"$TkGnats(LogName)" == "root"} {
    wm withdraw .
    Msg "You cannot edit problem reports as root.\n" "Please use your own login."
    incr numerrs
}

set CategoryList [get_categories]
if {$CategoryList == ""} {
    wm withdraw .
    Msg "The categories list is empty!"
    incr numerrs
}

if {$numerrs > 0} {
    exit 1
}

set  full_id [lock_pr $Tkeditpr(prid)]
if {$full_id == ""} {
    exit 1
}

set pr $GNATS_ROOT/$full_id
set stamp   tkeditpr.$TkGnats(LogName).[clock format [clock seconds] -format "%j:%T"]
set newfile /tmp/ep$stamp
file copy -force $pr $newfile

edit_window

tkwait window .

unlock_pr   $full_id
file delete $newfile
