# preferences.tcl --
#
# This file controls the preferences window. There is just one preferences
# window, if the user requests a new preferences window when the window
# already exists, it is just unmapped and raised (if possible).
#
#
#  TkRat software and its included text is Copyright 1996,1997,1998
#  by Martin Forssén
#
#  Postilion software and its included text and images
#  Copyright (C) 1998, 1999, 2000 Nic Bernstein
#
#  The full text of the legal notices is contained in the files called
#  COPYING and COPYRIGHT.TkRat, included with this distribution.
#
#  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; if not, write to the Free Software
#  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

# The last wisited window
set lastPref General

# Preferences --
#
# Make sure the user sees an preferences window.
#
# Arguments:

proc Preferences {} {
    global pref_oldFocus
    if ![winfo exists .preferences] {
	BuildPreferences
    } else {
	set pref_oldFocus [focus]
	wm deiconify .preferences
	focus .preferences
    }
}


# BuildPreferences --
#
# Builds the preferences window.
#
# Arguments:

proc BuildPreferences {} {
    global t b pref lastPref pref_oldFocus option

    # Initialize defaults
    set pref(options) {}
    set pref_oldFocus [focus]

    # A hack
#puts $option(from)
    set option(from_addr) [lindex $option(from) 0]
    set option(from_fn) [string trim [lreplace $option(from) 0 0] ()]
    set option(reply_to_addr) [lindex $option(reply_to) 0]
    set option(reply_to_fn) [string trim [lreplace $option(reply_to) 0 0] ()]
    
    # Initialize data table
    foreach l [GetLanguages] {
	if ![string length [GetFont [lindex $l 2] 0 {}]] {
	    continue
	}
	lappend lang [lrange $l 0 1]
    }
 
    # variable label type type_args
    #               entry unit_label
    #                 option options
    #               special procedure
    set pref(Startup) "\
       {iconic startup_mode option \
               {{1 {$t(iconic)}} {0 {$t(normal)}}}} \
       {info_changes show_changes option \
               {{1 {$t(show)}} {0 {$t(dont_show)}}}} \
       {next_menu menu_style option \
               {{1 {$t(next_style)}} {0 {$t(normal)}}}} \
       {start_win start_win special SetupStartWins} \
       {mail_steal check_stolen_mail option \
               {{1 {$t(check)}} {0 {$t(dont_check)}}}} \
     "
     set pref(General) "\
       {language language option [list $lang]} \
       {print_command print_command entry} \
       {print_header print_headers option \
               {{all {$t(all)}} {selected {$t(selected)}} {none {$t(none)}}}} \
       {print_non_text print_non_text option \
               {{1 {$t(do)}} {0 {$t(do_not)}}}} \
       {expunge_on_close expunge_on_close option \
	       {{1 {$t(do)}} {0 {$t(do_not)}}}} \
       {tmp tmp_dir entry} \
       {permissions file_permissions entry} \
       {userproc userproc_file entry} \
       {hold_dir hold_dir entry} \
       {fontsize character_size option \
               {{8 8} {10 10} {12 12} {14 14} {18 18} {24 24}}} \
       {keep_pos remember_pos option \
               {{1 {$t(do_remember)}} {0 {$t(dont_remember)}}}} \
       {mailcap_path mailcap_path entry} \
       {terminal terminal_command entry} \
     "
     set pref(Appearance) "\
       {color_set color_scheme special SetupColor} \
       {paper_color paper_color color} \
       {button_bar button_bar option \
               {{1 {$t(show)}} {0 {$t(dont_show)}}}} \
       {image_buttons buttons option \
               {{1 {$t(icon)}} {0 {$t(text)}}}} \
       {new_msg_col new_msg_col color} \
       {sel_msg_col sel_msg_col color} \
       {fnd_msg_col fnd_msg_col color} \
       {flg_msg_col flg_msg_col color} \
       {del_msg_col del_msg_col color} \
       {seen_msg_col seen_msg_col color} \
       {ans_msg_col ans_msg_col color} \
       {url_color url_color color} \
       {quote_color quote_color color} \
     "
     set pref(Browser) "\
       {sync_but sync_but option \
               {{1 {$t(show)}} {0 {$t(dont_show)}}}} \
       {sync_oper sync_oper option \
               {{1 {$t(sync)}} {0 {$t(update)}}}} \
       {mboxvis mboxvis option \
               {{1 {$t(show)}} {0 {$t(dont_show)}}}} \
       {message_llength messages_shown entry} \
       {clock_format clock_format option \
               {{12 {$t(12_hour)}} \
                {24 {$t(24_hour)}}}} \
       {list_mode default_list_format_mode option \
               {{normal {$t(normal)}} \
                {folder {$t(use_folder_default)}}}} \
       {list_format list_format entry} \
       {show_header show_headers option \
               {{all {$t(show_all_headers)}} \
                {selected {$t(show_selected_headers)}} \
                {none {$t(show_no_headers)}}}} \
       {show_header_selection show_header_selection entry} \
       {browse default_browse_mode option \
               {{normal {$t(no_browse)}} \
                {browse {$t(do_browse)}} \
                {folder {$t(use_folder_default)}}}} \
       {sort_mode default_sort_order_mode option \
               {{normal {$t(normal)}} \
                {folder {$t(use_folder_default)}}}} \
       {folder_sort sort_order option \
               {{subject {$t(subject_by_date)}} \
                {subjectonly {$t(subjectonly)}} \
                {sender {$t(bysender)}} \
                {folder {$t(natural_order)}} \
                {reverseFolder {$t(reverse_natural_order)}} \
                {date {$t(by_date)}} \
                {reverseDate {$t(reverse_date)}}}} \
       {adv_on_flag advance_on_flag option \
               {{1 {$t(true)}} \
                {0 {$t(false)}}}} \
       {strsel_mode default_start_selection_mode option \
               {{normal {$t(normal)}} \
                {folder {$t(use_folder_default)}}}} \
       {start_selection start_selection option \
               {{first {$t(first_message)}} \
                {last {$t(last_message)}} \
                {first_new {$t(first_new_message)}} \
                {before_new {$t(before_first_new_message)}}}} \
       {log_timeout log_timeout entry_unit {$t(seconds)}} \
       {cache_passwd cache_passwd option \
               {{1 {$t(do_cache)}} {0 {$t(do_not_cache)}}}} \
       {cache_passwd_timeout cache_timeout entry_unit {$t(seconds)}} \
       {cache_conn cache_conn option \
               {{1 {$t(do_cache)}} {0 {$t(do_not_cache)}}}} \
       {cache_conn_timeout cache_timeout entry_unit {$t(seconds)}} \
       {urlprot url_protocols entry} \
       {url_viewer url_viewer option \
               {{RatUP {$t(userproc): RatUP_ShowURL}} \
                {netscape Netscape}}} \
       {netscape netscape_cmd entry} \
       {netscape_args netscape_args entry} \
     "
     set pref(Dbase) "\
       {dbase_dir dbase_dir entry} \
       {def_extype extype option \
               {{none {$t(none)}} \
                {remove {$t(remove)}} \
                {incoming {$t(add_incoming)}} \
                {backup {$t(backup)}}}} \
       {def_exdate exdate entry_unit {$t(days)}} \
       {dbase_backup dbase_backup entry} \
       {chunksize chunksize entry} \
       {expire_interval expire_interval entry_unit {$t(days)}} \
     "
     set pref(Watcher) "\
       {watcher_enable watcher_enable option \
               {{1 {$t(enabled)}} {0 {$t(disabled)}}}} \
       {watcher_time intervals special SetupWatcherTime} \
       {watcher_name window_name entry} \
       {watcher_max_height max_height entry_unit {$t(lines)}} \
       {watcher_font font entry} \
       {watcher_show show_messages option \
               {{new {$t(new)}} {all {$t(all)}}}} \
       {watcher_format list_format entry} \
       {watcher_bell bell_ringings entry} \
     "
     set pref(Compose) "\
       {reply_mode default_reply_to_mode option \
               {{normal {$t(normal)}} \
                {folder {$t(use_folder_default)}}}} \
       {reply_to_addr default_reply_to_addr entry} \
       {reply_to_fn default_reply_to_fn entry} \
       {compose_headers headers entry} \
       {editor external_editor entry} \
       {attribution attribution entry} \
       {forwarded_message forwarded_label entry} \
       {reply_lead reply_lead entry} \
       {quote on_reply option \
               {{0 {$t(quote)}} {1 {$t(no_quote)}}}} \
       {skip_sig on_reply option \
               {{true {$t(skip_sig)}} {false {$t(keep_sig)}}}} \
       {no_subject no_subject entry} \
       {sig_mode default_signature_mode option \
               {{normal {$t(normal)}} \
                {folder {$t(use_folder_default)}}}} \
       {signature signature_file entry} \
       {lookup_name lookup_name option \
               {{true {$t(do_lookup)}} {false {$t(dont_lookup)}}}} \
       {copy_attached copy_attached_files option \
               {{1 {$t(true)}} {0 {$t(false)}}}} \
       {automatic_wrap automatic_wrap option \
               {{1 {$t(true)}} {0 {$t(false)}}}} \
       {automatic_indent automatic_indent option \
               {{1 {$t(true)}} {0 {$t(false)}}}} \
     "
    set pref(Ispell) "\
       {ispellon ispellOnOff option \
               {{1 {$t(true)}} \
                {0 {$t(false)}}}} \
       {ispellRecheckAfterAdd ispellRecheckAfterAdd option \
               {{1 {$t(true)}} \
                {0 {$t(false)}}}} \
       {ispelltextOnly ispellTextOnly option \
               {{1 {$t(true)}} \
                {0 {$t(false)}}}} \
       {ispelldefaultCommand ispellCommand entry} \
       {ispellotherCommands ispellOthers entry} \
       {ispellpopupBinding ispellPopupBinding entry} \
       {ispellviewStyle ispellStyle option \
               {{underline {$t(underline)}} \
                {italic {$t(italic)}} \
                {bold {$t(bold)}} \
                {bgcolor {$t(bgcolor)}} \
                {fgcolor {$t(fgcolor)}} \
                {other {$t(other)}}}} \
       {ispellviewStyle-Color ispellStyleColor color} \
       {ispellviewStyle-Other ispellStyleOther entry} \
     "
    set pref(Sending) "\
       {from_mode default_from_mode option \
               {{normal {$t(normal)}} \
                {folder {$t(use_folder_default)}}}} \
       {from_addr use_from_address entry} \
       {from_fn use_from_fn entry} \
       {masquerade_as masquerade_host_as entry} \
       {domain domain entry} \
       {delivery_mode delivery_mode option \
               {{direct {$t(direct)}} {deferred {$t(deferred)}}}} \
       {sendprot sendprot option \
               {{smtp {$t(smtp)}} {prog {$t(user_program)}}}} \
       {smtp_hosts smtp_hosts entry} \
       {smtp_timeout smtp_timeout entry_unit {$t(seconds)}} \
       {smtp_reuse smtp_reuse option \
               {{1 {$t(true)}} {0 {$t(false)}}}} \
       {smtp_verbose smtpv option \
               {{0 {$t(none)}} \
                {1 {$t(terse)}} \
                {2 {$t(normal)}} \
                {3 {$t(verbose)}}}} \
       {date-prefix prefix entry} \
       {sendprog sendprog entry} \
       {sendprog_8bit progin option \
               {{true {$t(eightbit)}} {false {$t(sevenbit)}}}} \
       {charset charset entry} \
       {force_send force_send option \
               {{1 {$t(force)}} {0 {$t(no_force)}}}} \
     "
     set pref(Notification) "\
       {dsn_directory dsn_directory entry} \
       {dsn_request default_action option \
               {{0 {$t(not_request_dsn)}} {1 {$t(request_dsn)}}}} \
       {dsn_snarf_reports folderwindow option \
               {{0 {$t(not_snarf_dsn)}} {1 {$t(snarf_dsn)}}}} \
       {dsn_expiration dsn_expiration entry_unit {$t(days)}} \
       {dsn_verbose report_level special SetupDSNVerbose} \
     "
     set pref(PGP) "\
       {pgp_enable pgp_handling option \
               {{1 {$t(enabled)}} {0 {$t(disabled)}}}} \
       {pgp_prog pgp_program entry} \
       {pgp_args pgp_extra_args entry} \
       {cache_pgp cache_passwd option \
               {{1 {$t(do_cache)}} {0 {$t(do_not_cache)}}}} \
       {cache_pgp_timeout cache_timeout entry_unit {$t(seconds)}} \
       {pgp_sign sign_outgoing option \
               {{1 {$t(true)}} {0 {$t(false)}}}} \
       {pgp_encrypt encrypt_outgoing option \
               {{1 {$t(true)}} {0 {$t(false)}}}} \
     "
 

    # Create toplevel
    set w .preferences
    toplevel $w -class Postilion
    wm title $w $t(preferences)
    wm iconname $w $t(preferences)
    wm group $w .
    wm protocol $w WM_DELETE_WINDOW \
	"PrefCheck; RecordSize $w.f.canvas prefCanvas; \
              RecordPos $w preferences; \
	      focus $pref_oldFocus; \
              destroy $w; destroy ${w}_icon"

    SetIcon $w prefwin

    upvar #0 $w pd
    set pd(win_type) preferences

    # The buttons
    frame $w.buttons
    frame $w.buttons.def -relief sunken -bd 1
    button $w.buttons.def.ok -text $t(apply) -command PrefApply
    pack $w.buttons.def.ok -padx 4 -pady 4
    button $w.buttons.cancel -text $t(reset) \
	    -command {
			global pref
			set pref(options) {}
		     }
    button $w.buttons.dismiss -text $t(dismiss) \
	    -command "PrefCheck; \
		      RecordSize $w.f.canvas prefCanvas;
		      RecordPos $w preferences;
		      destroy $w;
                      destroy ${w}_icon"
    pack $w.buttons.def \
	 $w.buttons.cancel \
         $w.buttons.dismiss -side left -expand 1
    bind $w <Return> PrefApply
    set b($w.buttons.def.ok) apply_prefs
    set b($w.buttons.cancel) cancel
    set b($w.buttons.dismiss) dismiss

    bind $w <FocusIn> "ConfigMainMenu $w"

    # Prepare for the tabs
    canvas $w.page -highlightthickness 0
    after idle [list PrefDrawTabs $w.page]
    set pref(tab) $w.page

    # The canvas
    frame $w.f -relief sunken -bd 1
    scrollbar $w.f.scroll \
	    -relief sunken \
	    -bd 1 \
	    -command "$w.f.canvas yview" \
	    -highlightthickness 0
    canvas $w.f.canvas \
	    -yscrollcommand "$w.f.scroll set" \
	    -highlightthickness 0
    # Scroll mouse support added by Stephen Ryan 14 Oct 1999
    bind $w.f.canvas <5> [list $w.f.canvas yview scroll 5 units]
    bind $w.f.canvas <4> [list $w.f.canvas yview scroll -5 units]
    bind $w.f.canvas <Shift-5> [list $w.f.canvas yview scroll 1 units]
    bind $w.f.canvas <Shift-4> [list $w.f.canvas yview scroll -1 units]
    bind $w.f.canvas <Control-5> [list $w.f.canvas yview scroll 1 pages]
    bind $w.f.canvas <Control-4> [list $w.f.canvas yview scroll -1 pages]
    Size $w.f.canvas prefCanvas
    pack $w.f.scroll -side right -fill y
    pack $w.f.canvas -side left -expand 1 -fill both
    set pref(frame) [frame $w.f.canvas.f]
    set pref(cid) [$w.f.canvas create window 0 0 \
	    -anchor nw \
	    -window $w.f.canvas.f]
    set pref(canvas) $w.f.canvas

    pack $w.page -side top -fill x
    pack $w.buttons -side bottom -fill x -pady 5
    pack $w.f -side top -pady 10 -expand 1 -fill both

    Place $w preferences

    PrefShow $lastPref
}

# PrefDrawTabs -
#
# Draw the tabs at the top of the page
#
# Arguments:
# w - Canvas to draw in

proc PrefDrawTabs {w} {
    global t lastPref

    set normalColor [$w cget -selectbackground]
    set activeColor [$w cget -background]
    set margin 6
    set x 2
    set maxh 0

    foreach name {Startup General Appearance Browser Dbase Watcher Compose Ispell Sending 
	Notification PGP} {
	set id [$w create text [expr $x+$margin+2] [expr -0.5*$margin] \
		-anchor sw -text $t([string tolower $name]) -tags $name]
	set bbox [$w bbox $id]
	set wd [expr [lindex $bbox 2]-[lindex $bbox 0]]
	set ht [expr [lindex $bbox 3]-[lindex $bbox 1]]
	if {$ht > $maxh} {
	    set maxh $ht
	}

	$w create polygon 0 0  $x 0 \
		[expr $x+$margin] [expr -$ht-$margin] \
		[expr $x+$margin+$wd] [expr -$ht-$margin] \
		[expr $x+$wd+2*$margin] 0 \
		2000 0  2000 10  0 10 \
		-outline black -fill $normalColor \
		-tags [list $name tab tab-$name]
	$w raise $id
	$w bind $name <ButtonPress-1> "PrefCheck; PrefShow $name"

	incr x [expr $wd+2*$margin]
    }
    set height [expr $maxh+2*$margin]
    $w move all 0 $height
    $w configure -width $x -height [expr $height+4]

    $w itemconfigure tab-$lastPref -fill $activeColor
    $w raise $lastPref
}

# PrefShow --
#
# Show a preferences window
#
# Arguments:
# pane - Which pane of preferences to show

proc PrefShow {pane} {
    global t b option pref lastPref

    set w $pref(tab)
    $w itemconfigure tab -fill [$w cget -selectbackground]
    $w itemconfigure tab-$pane -fill [$w cget -background]
    $w raise $pane

    set f $pref(frame)
    set s [grid slaves $f]
    if [llength $s] {
	eval "destroy $s"
    }
    foreach bn [array names b $f.*] {unset b($bn)}
    set row 0

    set pref(options) {}
    foreach p $pref($pane) {
	set var [lindex $p 0]
	lappend pref(options) $var
	set pref(opt,$var) $option($var)
	label $f.r${row}_lab -text $t([lindex $p 1]):
	grid $f.r${row}_lab -row $row -sticky ne -pady 5
	switch [lindex $p 2] {
	    entry {
		entry $f.r${row}_item -textvariable pref(opt,$var) \
		    -width 60
		grid $f.r${row}_item - -row $row -column 1 -sticky we
		set b($f.r${row}_item) pref_$var
	    }
	    entry_unit {
		entry $f.r${row}_item -textvariable pref(opt,$var)
		label $f.r${row}_unit -text ([lindex $p 3])
		grid $f.r${row}_item -row $row -column 1 -sticky we
		grid $f.r${row}_unit -row $row -column 2 -sticky we
		set b($f.r${row}_item) pref_$var
		set b($f.r${row}_unit) unit_pref
		}
	    option {
		OptionMenu $f.r${row}_item pref(opt,$var) \
		    pref(text,$var) [lindex $p 3]
		grid $f.r${row}_item - -row $row -column 1 -sticky w
		set b($f.r${row}_item) pref_$var
	    }
	    color {
		ColorMenu $f.r${row}_item pref(opt,$var) [lindex $p 1]
		grid $f.r${row}_item - -row $row -column 1 -sticky w
		set b($f.r${row}_item) pref_$var
	    }
	    special {
		[lindex $p 3] $f.r${row}_item
		grid $f.r${row}_item - -row $row -column 1 -sticky w
	    }
	    default {puts "Internal error <$p>"}
	}
	if [RatIsLocked option([lindex $p 0])] {
	    $f.r${row}_item configure -state disabled -relief flat
	}

	incr row
    }

    grid columnconfigure $f 1 -weight 1

    set lastPref $pane

    update idletasks
    set bbox [$pref(canvas) bbox $pref(cid)]
    eval {$pref(canvas) configure -scrollregion $bbox}
}

# PrefApply --
#
# Applies any changes to the preferences made in the current window.
#
# Arguments:

proc PrefApply {} {
    global option pref t folderWindowList composeWindowList lastPref

    switch $lastPref {
	Startup {
	    set pref(opt,start_win) [list [list mailboxes $pref(opt,mailboxes)] \
					 [list compose $pref(opt,compose)] \
					 [list address $pref(opt,address)] \
					 [list browser $pref(opt,browser)]]
	}
	General {
	    if [string compare $option(mailcap_path) $pref(opt,mailcap_path)] {
		RatMailcapReload
	    }
	}
	Appearance {
	    if [string compare $option(paper_color) $pref(opt,paper_color)] {
		foreach fw $folderWindowList {
		    upvar #0 $fw fh
		    $fh(text) configure -background $pref(opt,paper_color)
		}
		foreach cw $composeWindowList {
		    upvar #0 $cw fh
		    $fh(composeBody) configure \
			-background $pref(opt,paper_color)
		}
	    }
	    if [string compare $option(url_color) $pref(opt,url_color)] {
		foreach fw $folderWindowList {
		    upvar #0 $fw fh
		    $fh(text) tag configure URL \
			-foreground $pref(opt,url_color)
		}
	    }
	    if [string compare $option(new_msg_col) $pref(opt,new_msg_col)] {
		foreach fw $folderWindowList {
		    upvar #0 $fw fh
		    $fh(msgList).list configure \
			-foreground $pref(opt,new_msg_col)
		}
	    }
	    if [string compare $option(sel_msg_col) $pref(opt,sel_msg_col)] {
		foreach fw $folderWindowList {
		    upvar #0 $fw fh
		    $fh(msgList).list tag configure sel \
			-background $pref(opt,sel_msg_col)
		}
	    }
	    if [string compare $option(fnd_msg_col) $pref(opt,fnd_msg_col)] {
		foreach fw $folderWindowList {
		    upvar #0 $fw fh
		    $fh(msgList).list tag configure Found \
			-background $pref(opt,fnd_msg_col)
		}
	    }
	    if [string compare $option(flg_msg_col) $pref(opt,flg_msg_col)] {
		foreach fw $folderWindowList {
		    upvar #0 $fw fh
		    $fh(msgList).list tag configure flagged \
			-foreground $pref(opt,flg_msg_col)
		}
	    }
	    if [string compare $option(del_msg_col) $pref(opt,del_msg_col)] {
		foreach fw $folderWindowList {
		    upvar #0 $fw fh
		    $fh(msgList).list tag configure deleted \
			-foreground $pref(opt,del_msg_col)
		}
	    }
	    if [string compare $option(seen_msg_col) $pref(opt,seen_msg_col)] {
		foreach fw $folderWindowList {
		    upvar #0 $fw fh
		    $fh(msgList).list tag configure seen \
			-foreground $pref(opt,seen_msg_col)
		}
	    }
	    if [string compare $option(ans_msg_col) $pref(opt,ans_msg_col)] {
		foreach fw $folderWindowList {
		    upvar #0 $fw fh
		    $fh(msgList).list tag configure answered \
			-foreground $pref(opt,ans_msg_col)
		}
	    }
	}
	Watcher {
	    set pref(opt,watcher_time) [list [list std $pref(opt,finterval)] \
					     [list dbase $pref(opt,dinterval)]]
	}
	Notification {
	    set pref(opt,dsn_verbose) [list [list failed $pref(opt,failed)] \
					[list delayed $pref(opt,delayed)] \
					[list delivered $pref(opt,delivered)] \
					[list relayed $pref(opt,relayed)] \
					[list expanded $pref(opt,expanded)]]
	}
	Compose {
	    if {[string compare $option(signature) $pref(opt,signature)]
		    && 1 == [llength [info commands RatUP_Signature]]} {
		Popup $t(sig_cmd_takes_precedence)
	    }
	    set pref(opt,reply_to) \
		[concat $pref(opt,reply_to_addr) ($pref(opt,reply_to_fn))]
	    lappend pref(options) reply_to
#puts $pref(opt,reply_to)
	}
	Ispell {
	    foreach pick {on RecheckAfterAdd textOnly defaultCommand
		otherCommands popupBinding viewStyle viewStyle-Color 
		viewStyle-Other} {
		set ispellVars($pick) $pref(opt,ispell$pick)
	    }
	}
	Sending {
	    if {[string compare $option(sendprog) $pref(opt,sendprog)]
		    && ![file executable [lindex $pref(opt,sendprog) 0]]} {
		Popup $t(warning_sendprog)
	    }
	    set pref(opt,from) \
		[concat $pref(opt,from_addr) ($pref(opt,from_fn))]
	    lappend pref(options) from
#puts $pref(opt,from)
	}
	Browser {
	    if [string compare $option(message_llength) \
			       $pref(opt,message_llength)] {
		foreach fw $folderWindowList {
		    upvar #0 $fw fh
		    $fh(message_list) configure \
			    -height $pref(opt,message_llength)
		}
	    }
	}
	PGP {
	    if {[string compare $option(pgp_prog) $pref(opt,pgp_prog)]
		    && ![file executable [lindex $pref(opt,pgp_prog) 0]]} {
		Popup $t(warning_pgp_prog)
	    }
	}
    }

    set hasChanged 0
    set needRestart 0
    set newSendArgs 0
    foreach opt $pref(options) {
	if [string compare $option($opt) $pref(opt,$opt)] {
	    set option($opt) $pref(opt,$opt)
	    set hasChanged 1
	    if { -1 != [lsearch -exact {language charset fontsize
		main_window_name image_buttons next_menu
		default_folder watcher_name pgp_enable} $opt]} {
		set needRestart 1
	    }
	    if { -1 != [lsearch -exact {charset masquerade_as domain sendprot
					smtp_hosts sendprog sendprog_8bit
					charset from smtp_verbose
					delivery_mode smtp_timeout force_send
					pgp_prog pgp_args} $opt]} {
		set newSendArgs 1
	    }
	}
    }

    if $hasChanged {
	switch $lastPref {
	Browser {
		foreach f $folderWindowList {
		    Sync $f 0
		}
	    }
	}

	SaveOptions
    }
    if $newSendArgs {
	RatSend kill
    }
    if $needRestart {
	bind .preferences <FocusIn> ""
	Popup $t(need_restart)
	Quit all
}
}


# PrefCheck --
#
# Checks if there are any unapplied changes and if there is the user is
# queried if he wants to apply them.
#
# Arguments:

proc PrefCheck {} {
    global option pref t lastPref

    switch $lastPref {
	Startup {
	    set pref(opt,start_win) [list \
				[list mailboxes $pref(opt,mailboxes)] \
					 [list compose $pref(opt,compose)] \
					 [list address $pref(opt,address)] \
					 [list browser $pref(opt,browser)]]
	}
	Watcher {
	    set pref(opt,watcher_time) [list [list std $pref(opt,finterval)] \
					     [list dbase $pref(opt,dinterval)]]
	}
	Notification {
	    set pref(opt,dsn_verbose) [list [list failed $pref(opt,failed)] \
					[list delayed $pref(opt,delayed)] \
					[list delivered $pref(opt,delivered)] \
					[list relayed $pref(opt,relayed)] \
					[list expanded $pref(opt,expanded)]]
	}
    }
    foreach opt $pref(options) {
	if [string compare $option($opt) $pref(opt,$opt)] {
            set value [RatDialog $t(unapplied_changes_title) \
		    $t(unapplied_changes) {} 0 $t(apply) $t(discard)]
	    if { 0 == $value } {
		PrefApply
	    }
	    return
	}
    }
}


# OptionMenu --
#
# Generates an option menu. The generated menu will have window name "w"
# and will set the "varName" variable. The different options are
# controlled by the value arguments. Each value argument is a list of
# two elemnts. The first is the value to set "varName" to and the second
# is the text to show. The menubutton will use "textVar" as the textvariable.
#
# Arguments:
# w	  -	Name of menubutton to create
# varName -	Variable to set to value
# textVar -	Variable to use for the text we show
# values  -	A list of lists which describes the values of this button

proc OptionMenu {w varName textVar values} {
    upvar #0 $varName var
    upvar #0 $textVar text

    set width 20
    menubutton $w -textvariable $textVar -indicatoron 1 \
		  -relief raised -menu $w.m
    menu $w.m -tearoff 0
    foreach elem $values {
	if ![string compare [lindex $elem 0] $var] {
	    set text [lindex $elem 1]
	}
	$w.m add command -label [lindex $elem 1] \
		-command "set $varName [list [lindex $elem 0]]; \
			  set $textVar [list [lindex $elem 1]]"
	if { $width < [string length [lindex $elem 1]]} {
	    set width [string length [lindex $elem 1]]
	}
    }
    $w configure -width $width
}

# ColorMenu --
#
# Generates a color menu. The generated menu will have window name "w"
# and will set the "varName" variable. The different options are
# controlled by the value arguments. Each value argument is a list of
# two elemnts. The first is the value to set "varName" to and the second
# is the text to show. The menubutton will use "textVar" as the textvariable.
#
# Arguments:
# w	  -	Name of menubutton to create
# varName -	Variable to set to value
# txt     -     Text of color to choose

proc ColorMenu {w varName txt} {
    global pref
    upvar #0 $varName var

    button $w -relief raised -bg $var -activebackground $var \
	-command "PickColor $w $varName $txt"
}

proc PickColor {w varName txt} {
    global t
    upvar #0 $varName var

    set newvar [tk_chooseColor -initialcolor $var -title $t($txt)]
    if [string length $newvar] {
	$w configure -bg $newvar
	set var $newvar
    }
}

proc SetupColor {w} {
    global t option pref tk_version

    if {$tk_version < 8.0} {
	button $w -width 21 -text $t(out_of_order) \
	    -command [list Popup $t(colorbug)]
	return
    }

    menubutton $w -textvariable pref(text,color_set) \
	-indicatoron 1 -relief raised -menu $w.m
    menu $w.m -tearoff 0

    set width 20
    foreach c { {gray67 black} {PeachPuff2 black} {bisque black}
		{SlateBlue1 black} {SteelBlue4 white} {SkyBlue1 black}
		{aquamarine2 black} {SpringGreen4 black}} {
	set name $t([lindex $c 0])
	if ![string compare $c $option(color_set)] {
	    set pref(text,color_set) $name
	}
	$w.m add command -label $name \
		-command "set pref(opt,color_set) [list $c]; \
			  set pref(text,color_set) [list $name]; \
			  SetColor $c" \
		-background [lindex $c 0] -foreground [lindex $c 1]
	if { $width < [string length $name]} {
	    set width [string length $name]
	}
    }
    $w configure -width $width
}


proc SetupWatcherTime {w} {
    global t option pref

    frame $w
    label $w.flabel -text $t(stdfolders):
    entry $w.fentry -textvariable pref(opt,finterval)
    label $w.funit -text ($t(seconds))
    if [RatIsLocked option(watcher_time)] {
        $w.fentry configure -state disabled -relief flat
    }
    label $w.dlabel -text $t(dbase_folders):
    entry $w.dentry -textvariable pref(opt,dinterval)
    label $w.dunit -text ($t(seconds))
    if [RatIsLocked option(watcher_time)] {
        $w.dentry configure -state disabled -relief flat
    }
    foreach elem $option(watcher_time) {
	if ![string compare [lindex $elem 0] std] {
	    set pref(opt,finterval) [lindex $elem 1]
	}
	if ![string compare [lindex $elem 0] dbase] {
	    set pref(opt,dinterval) [lindex $elem 1]
	}
    }
    grid $w.flabel -row 0 -column 0 -sticky e
    grid $w.fentry -row 0 -column 1 -sticky we
    grid $w.funit -row 0 -column 2 -sticky we
    grid $w.dlabel -row 1 -column 0 -sticky e
    grid $w.dentry -row 1 -column 1 -sticky we
    grid $w.dunit -row 1 -column 2 -sticky we
    grid columnconfigure $w 1 -weight 1
}

proc SetupDSNVerbose {w} {
    global option t pref

    foreach elem $option(dsn_verbose) {
	set pref(opt,[lindex $elem 0]) [lindex $elem 1]
    }
    frame $w
    set irow 0
    foreach cat {failed delayed delivered relayed expanded} {
	set sf $w.$cat
	label ${sf}_l -text $t($cat): -width 12 -anchor e
	OptionMenu ${sf}_mbut pref(opt,$cat) pref(text,$cat) \
		[list [list none $t(rl_none)] \
		      [list status $t(rl_status)] \
		      [list notify $t(rl_notify)]]
	if [RatIsLocked option(dsn_verbose)] {
	    ${sf}_mbut configure -state disabled
	}
	grid ${sf}_l -row $irow -column 0 -sticky e
	grid ${sf}_mbut -row $irow -column 1 -sticky w
	incr irow
    }
}

proc SetupStartWins {w} {
    global option t pref

    frame $w
    set irow 0
    foreach elem $option(start_win) {
	set cat [lindex $elem 0]
	set pref(opt,$cat) [lindex $elem 1]
	set sf $w.$cat
	label ${sf}_l -text $t($cat): -width 12 -anchor e
	OptionMenu ${sf}_mbut pref(opt,$cat) pref(text,$cat) \
	    [list [list 1 $t(show)] \
		 [list 0 $t(dont_show)]]
	grid ${sf}_l -row $irow -column 0 -sticky e
	grid ${sf}_mbut -row $irow -column 1 -sticky w
	incr irow
    }
}

# PrefProbeDSN --
#
# Probe the current SMTP servers for DSN support.
#
# Arguments:

proc PrefProbeDSN {} {
    global idCnt option t defaultFont

    # Create identifier
    set id probeWin[incr idCnt]
    upvar #0 $id hd
    set w .$id
    set hd(w) $w

    # Create toplevel
    toplevel $w -class Postilion
    wm title $w $t(probe)

    if [string compare $option(sendprot) smtp] {
	message $w.message -aspect 600 -text $t(dsn_need_smtp)
	button $w.button -text $t(dismiss) \
		-command "RecordPos $w prefProbeDSN; destroy $w; unset $id"
	pack $w.message \
	     $w.button -side top -padx 5 -pady 5
	return
    }

    set row 0
    foreach h $option(smtp_hosts) {
	label $w.l$row -text $h -width 32 -anchor e
	label $w.a$row -textvariable ${id}($h) -font $defaultFont -width 32 \
		-anchor w
	grid $w.l$row -row $row -column 0 -sticky e
	grid $w.a$row -row $row -column 1 -sticky w
	incr row
    }
    button $w.button -text $t(dismiss) -command "destroy $w; unset $id" \
	    -state disabled
    grid $w.button -row $row -column 0 -columnspan 2
    Place $w prefProbeDSN

    foreach h $option(smtp_hosts) {
        set hd($h) $t(probing)...
	update idletasks
	if [RatSMTPSupportDSN $h] {
	    set hd($h) $t(supports_dsn)
	} else {
	    set hd($h) $t(no_dsn_support)
	}
    }
    $w.button configure -state normal
}
