diff options
Diffstat (limited to 'Master/texmf-dist/scripts/epspdf/epspdftk.tcl')
-rwxr-xr-x | Master/texmf-dist/scripts/epspdf/epspdftk.tcl | 848 |
1 files changed, 848 insertions, 0 deletions
diff --git a/Master/texmf-dist/scripts/epspdf/epspdftk.tcl b/Master/texmf-dist/scripts/epspdf/epspdftk.tcl new file mode 100755 index 00000000000..ac96d844be7 --- /dev/null +++ b/Master/texmf-dist/scripts/epspdf/epspdftk.tcl @@ -0,0 +1,848 @@ +#!/usr/bin/env wish + +# epspdf conversion utility, GUI frontend + +##### +# Copyright (C) 2006, 2008, 2009, 2010 Siep Kroonenberg +# n dot s dot kroonenberg at rug dot nl +# +# This program is free software, licensed under the GNU GPL, >=2.0. +# This software comes with absolutely NO WARRANTY. Use at your own risk! +##### + +package require Tk + +# tired of writing out this combined test again and again +set classic_unix [expr {$::tcl_platform(platform) eq "unix" && \ + $::tcl_platform(os) ne "Darwin"}] + +# normally, epspdf.rb should be in the same directory +# and ruby should be on the searchpath. +# However, the Windows installer version includes a Ruby subset +# and wraps this script in a starpack. + +### calling epspdf.rb ######################### + +# Get full path of epspdf.rb. It should be in the same directory as +# either this script or of the starpack containing this script. +# For the windows-only starpack, a ruby subset is included. +# Otherwise, ruby should be on the searchpath. + +proc set_progs {} { + # starpack edition? + set starred 0 + if {$::tcl_platform(platform) eq "windows"} { + foreach l [info loaded] { + if {[lindex $l 1] eq "tclkitpath"} { + set starred 1 + break + } + } + } + if {$starred} { + set eproot [file normalize \ + [regsub {([\\/])([^\\/]+)$} [info nameofexecutable] {}]] + set ::ruby [file normalize "$eproot/../rubysub/bin/ruby.exe"] + } else { + set eproot [file normalize \ + [regsub {([\\/])([^\\/]+)$} [info script] {}]] + set ::ruby "ruby" + } + set ::epspdf_rb [file join $eproot "epspdf.rb"] + if {! [file exists $::epspdf_rb]} { + tk_messageBox -type ok -icon error -message "Epspdf.rb not found" + exit 1 + } + + # no luck with other platforms + if {$::tcl_platform(platform) eq "windows"} { + wm iconbitmap . [file join $eproot "epspdf.ico"] + } +} + +set_progs + +# call epspdf.rb with parameter list l (should be a list): + +set result "" +proc run_epspdf {res args} { + upvar $res result + set failed [catch [linsert $args 0 exec $::ruby $::epspdf_rb --gui] result] + if {$failed} { + wm deiconify .log_t + tk_messageBox -icon error -type ok -message "Error; see log window" + } + # update log window with $result + .log_t.text configure -state normal + .log_t.text insert end "$result\n" + .log_t.text yview moveto 1 + .log_t.text configure -state disabled + + # it is up to the caller to do anything else about failure or not. + # the user, at least, has been warned. + return [expr ! $failed] +} + +### read configured settings ######################################## + +# for checking configured viewers under non-osx unix +proc is_valid {x} { + if {[catch {exec which $x}]} {return 0} else {return 1} +} + +# create a global empty settings array +array set settings [list] + +# ask epspdf.rb for currently configured settings. +# this does not include automatically configured or transient settings. +# the availability of viewers is handled here. +proc getsettings {} { + if [catch {exec $::ruby $::epspdf_rb --gui=config_w} set_str] { + error "Epspdf configuration error: $set_str" + } + #puts "settings from epspdf.rb:\n$set_str" + set l [split $set_str "\r\n"] + foreach e $l { + # $e is either a string "var=value" + # or the empty string between <cr> and <lf> + set i [string first "=" $e] + if {$i>0} { + #puts $e + set ::settings([string range $e 0 [expr $i-1]]) \ + [string range $e [expr $i+1] end] + } + } + + # unix: viewer settings + # configured viewer, if valid, heads the list + if {$::classic_unix} { + + set ::ps_viewers {} + if {$::settings(ps_viewer) ne "" && [is_valid $::settings(ps_viewer)]} { + lappend ::ps_viewers $::settings(ps_viewer) + } + foreach v {evince okular gv kghostview ghostview} { + if {$v ne $::settings(ps_viewer) && [is_valid $v]} { + lappend ::ps_viewers $v + } + } + + set ::pdf_viewers {} + if {$::settings(pdf_viewer) ne "" && [is_valid $::settings(pdf_viewer)]} { + lappend ::pdf_viewers $::settings(pdf_viewer) + } + foreach v {evince okular kpdf xpdf epdfview acroread \ + gv kghostview ghostview} { + if {$v ne $::settings(pdf_viewer) && [is_valid $v]} { + lappend ::pdf_viewers $v + } + } + + if {[llength ::pdf_viewers] == 0 && [llength ::ps_viewers] != 0} { + lappend ::pdf_viewers [lindex $::ps_viewers 0] + } + if {[llength ::pdf_viewers] == 0} { + tk_messageBox -message "No viewers found" + } elseif {[llength ::ps_viewers] == 0} { + tk_messageBox -message "No PostScript viewers found" + } + if {[llength ::pdf_viewers] > 0} { + set ::settings(pdf_viewer) [lindex $::pdf_viewers 0] + } + if {[llength ::ps_viewers] > 0} { + set ::settings(ps_viewer) [lindex $::ps_viewers 0] + } + } +} + +getsettings + +# directory and other file data + +if {$::argc > 0 && [file isdirectory [lindex $::argv 0]]} { + set gfile(dir) [lindex $::argv 0] +} elseif {[file isdirectory $::settings(defaultDir)]} { + set gfile(dir) $::settings(defaultDir) +} else { + set gfile(dir) $::env(HOME) +} +set gfile(path) "" +set gfile(type) "" +set gfile(name) "" +set gfile(npages) "" + +# transient options +array set options [list gray "color" format "pdf" bbox 0 clean 1 \ + pages "single" page 1] + +proc viewable {} { + if { $::gfile(name) eq "" || ! [file exists $::gfile(path)] || \ + $::gfile(type) eq "other" || $::gfile(type) eq ""} { + return 0 + } elseif {! $::classic_unix} { + return 1 + } elseif {$::settings(ps_viewer) ne "" && [regexp {ps} $::gfile(type)]} { + return 1 + } elseif {$::settings(pdf_viewer) ne "" && $::gfile(type) eq "pdf"} { + return 1 + } else { + return 0 + } +} + +### groundwork for GUI ################################# + +# padding for buttons and frames +proc packb {b args} { + eval [linsert $args 0 pack $b -padx 3 -pady 3] + $b configure -border 2 +} + +proc packf {f args} { + eval [linsert $args 0 pack $f -padx 3 -pady 3] +} + +# dummy widget for vertical spacing +set idummy -1 +proc spacing {w} { + incr ::idummy + pack [label $w.$::idummy -text " "] +} + +# bold font +font create boldfont +# create dummy label widget to get at the default label font properties +label .dummy +font configure boldfont -family [font actual [.dummy cget -font] -family] +font configure boldfont -size [font actual [.dummy cget -font] -size] +font configure boldfont -weight bold +destroy .dummy + +# bitmaps for mycombo (no combobox in core tk8.4) +image create bitmap dwnarrow -data { +#define dwnarrow_width 15 +#define dwnarrow_height 10 +static unsigned char dwnarrow_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0xfc, 0x1f, 0xf8, 0x0f, 0xf0, 0x07, 0xe0, 0x03, + 0xc0, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00 }; +} + +image create bitmap uparrow -data { +#define uparrow_width 15 +#define uparrow_height 10 +static unsigned char uparrow_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0xc0, 0x01, 0xe0, 0x03, 0xf0, 0x07, + 0xf8, 0x0f, 0xfc, 0x1f, 0x00, 0x00, 0x00, 0x00 }; +} + +# mycombo +proc mycombo {w} { + # entry widget and dropdown button + frame $w + frame $w.ef + entry $w.ef.e -width 30 -borderwidth 1 + pack $w.ef.e -side left + button $w.ef.b -image dwnarrow -command "droplist $w" -borderwidth 1 + pack $w.ef.b -side right + pack $w.ef + # 'drop-down' listbox; width should match entry widget above + toplevel $w.lf -bd 0 + listbox $w.lf.l -yscrollcommand "$w.lf.s set" -height 4 -width 30 \ + -bd 1 -relief raised + grid $w.lf.l -column 0 -row 0 -sticky news + scrollbar $w.lf.s -command "$w.lf.l yview" -bd 1 + grid $w.lf.s -column 1 -row 0 -sticky ns + grid columnconfigure $w.lf 0 -weight 1 + wm overrideredirect $w.lf 1 + wm transient $w.lf + wm withdraw $w.lf + # next two bindings: + # final parameter: unmap/toggle listbox + bind $w.lf.l <KeyRelease-space> {update_e %W [%W get active] 1} + bind $w.lf.l <KeyRelease-Tab> {update_e %W [%W get active] 1} + bind $w.lf.l <FocusOut> {update_e %W [%W get active] 1} + bind $w.lf.l <1> {update_e %W [%W get @%x,%y] 0} + bind $w.lf.l <Double-1> {update_e %W [%W get @%x,%y] 1} + bind $w.ef.e <Return> {update_l %W} + bind $w.ef.e <Tab> {update_l %W} + bind $w.ef.e <FocusOut> {update_l %W} + return $w +} + +# toggle state of listbox. +# this involves calculating the place where it should appear +# and toggling the arrow image. +proc droplist {w} { + # $w.ef is the frame with the entry widget + # $w.lf is the toplevel with the listbox + # which needs to turn up right below $w.ef + if {[wm state $w.lf] eq "withdrawn" || [wm state $w.lf] eq "iconified"} { + set lfx [winfo rootx $w.ef] + set lfy [expr [winfo rooty $w.ef] + [winfo height $w.ef]] + wm geometry $w.lf [format "+%d+%d" $lfx $lfy] + wm deiconify $w.lf + $w.ef.b configure -image uparrow + } else { + wm withdraw $w.lf + $w.ef.b configure -image dwnarrow + } +} + +proc update_e {lbox vl unmap} { + set w [winfo parent [winfo parent $lbox]] + $w.ef.e delete 0 end + $w.ef.e insert 0 $vl + if {$unmap} {droplist $w} +} + +# entry => list +proc update_l {v} { + set t [$v get] + set w [winfo parent [winfo parent $v]] + for {set i 0} {$i<[$w.lf.l size]} {incr i} { + if {$t eq [$w.lf.l get $i]} { + $w.lf.l see $i + $w.lf.l activate $i + return + } + } + # $t not found + if {[$v validate]} { + $w.lf.l insert 0 $t + $w.lf.l see 0 + $w.lf.l activate 0 + } else { + tk_messageBox -message "Not a program" + } +} + +# end mycombo + +### and now the actual GUI ################################### + +wm title . "PostScript- and pdf conversions" + +# help toplevel + +proc readhelp {} { + .help_t.text configure -state normal + set helpfile [regsub {\.rb$} $::epspdf_rb {.help}] + if {[catch {set fid [open $helpfile r]}]} { + .help_t.text insert end "No helpfile $helpfile found\n" + } else { + while {[gets $fid line] >= 0} {.help_t.text insert end "$line\n"} + close $fid + } + .help_t.text configure -state disabled + .help_t.text yview moveto 0 +} + +toplevel .help_t +wm title .help_t "EpsPdf help" +packb [button .help_t.done -text "Close" -command {wm withdraw .help_t}] \ + -side bottom -anchor e -padx 50 +text .help_t.text -wrap word -width 60 -height 20 -setgrid 1 \ + -yscrollcommand ".help_t.scroll set" +scrollbar .help_t.scroll -command ".help_t.text yview" +pack .help_t.scroll -side right -fill y +pack .help_t.text -expand 1 -fill both +readhelp +.help_t.text configure -state disabled +wm withdraw .help_t + +# log toplevel + +toplevel .log_t +wm title .log_t "Epspdf log" +packb [button .log_t.b -text "Close" -command {wm withdraw .log_t}] \ + -side bottom -anchor e -padx 50 +text .log_t.text -wrap word -relief flat -height 15 -width 60 \ + -setgrid 1 -yscrollcommand ".log_t.scroll set" +scrollbar .log_t.scroll -command ".log_t.text yview" +pack .log_t.scroll -side right -fill y +pack .log_t.text -expand 1 -fill both +.log_t.text configure -state disabled +wm withdraw .log_t + +### configure toplevel ################### + +toplevel .config_t +wm title .config_t "Configure epspdf" + +# The settings array is edited directly in the configuration screen: +# for most control widgets, we need a global external variable anyway, +# so we better use the global that is already there. +# If the configuration screen is closed via the cancel button, +# the original values will be re-read from disk. +# If it is closed via the ok button, the new settings are written to disk. + +# viewers (not on windows or osx) + +if {$::classic_unix} { + packf [frame .config_t.viewf] -ipadx 4 -fill x + grid [label .config_t.viewf.title -font boldfont -text "Viewers"] \ + -row 0 -column 0 -sticky w + grid [label .config_t.viewf.lb_pdf -text "Pdf"] \ + -row 1 -column 0 -sticky w + grid [mycombo .config_t.viewf.pdf] -row 1 -column 1 -sticky e + .config_t.viewf.pdf.ef.e configure -vcmd {is_valid %P} -validate none + .config_t.viewf.pdf.ef.e configure -textvariable settings(pdf_viewer) + grid [label .config_t.viewf.lb_ps -text "PostScript"] \ + -row 2 -column 0 -sticky w + grid [mycombo .config_t.viewf.ps] -row 2 -column 1 -sticky e -pady 4 + .config_t.viewf.ps.ef.e configure -vcmd {is_valid %P} -validate none + .config_t.viewf.ps.ef.e configure -textvariable settings(ps_viewer) + grid columnconfigure .config_t.viewf 1 -weight 1 -pad 2 + + .config_t.viewf.pdf.lf.l configure -listvariable ::pdf_viewers + .config_t.viewf.ps.lf.l configure -listvariable ::ps_viewers + + spacing .config_t +} + +# settings for conversion to pdf + +packf [frame .config_t.pdff] -ipadx 4 -fill x +pack [label .config_t.pdff.title -font boldfont -text "Conversion to pdf"] \ + -anchor w + +pack [label .config_t.pdff.l_target -text "Target use"] -anchor w +pack [frame .config_t.pdff.f_targets] -fill x +foreach t {default printer prepress screen ebook} { + pack [radiobutton .config_t.pdff.f_targets.$t \ + -variable settings(pdf_target) \ + -text $t -value $t] -side left -padx 2 -pady 4 -anchor w +} + +pack [label .config_t.pdff.l_version -text "Pdf version"] -anchor w +pack [frame .config_t.pdff.f_version] -fill x +foreach t {1.2 1.3 1.4 default} { + regsub {\.} $t _ tp ; # replace dot in name: dots are path separators! + pack [radiobutton .config_t.pdff.f_version.$tp \ + -variable settings(pdf_version) \ + -text $t -value $t] -side left -padx 2 -pady 4 -anchor w +} + +pack [label .config_t.pdff.l_gs \ + -text "Custom Ghostscript/ps2pdf parameters"] -anchor w +pack [entry .config_t.pdff.e_gs -border 1] -fill x -padx 2 -pady 2 +.config_t.pdff.e_gs configure -textvariable settings(pdf_custom) + +spacing .config_t + +# settings for conversion to EPS and PostScript + +packf [frame .config_t.psf] -ipadx 4 -fill x +pack [label .config_t.psf.l_ps -text "Conversion to EPS and PostScript" \ + -font boldfont] -anchor w +if {$tcl_platform(platform) eq "windows"} { + pack [label .config_t.psf.l_pdftops -text "Find pdftops"] -anchor w + pack [frame .config_t.psf.findf] -anchor w + pack [entry .config_t.psf.findf.e -width 40] -side left -padx 4 + .config_t.psf.findf.e configure -textvariable settings(pdftops_prog) + # epspdfrc.rb already checked on this setting so we don't + packb [button .config_t.psf.findf.b -text "Browse..." \ + -command find_pdftops] -side left +} + +proc find_pdftops {} { + set try [tk_getOpenFile -title "Find pdftops.exe" \ + -filetypes {{"Programs" {.exe}}} -initialdir "c:/"] + if {$try ne ""} { + .config_t.psf.findf.e delete 0 end + .config_t.psf.findf.e insert 0 $try + } +} + +pack [checkbutton .config_t.psf.c \ + -text "Use pdftops if available (recommended)"] -anchor w +.config_t.psf.c configure \ + -variable settings(ignore_pdftops) -onvalue 0 -offvalue 1 + +spacing .config_t + +# hires boundingbox setting + +packf [frame .config_t.hiresf] -ipadx 4 -fill x +pack [label .config_t.hiresf.title -font boldfont -text "Hires BoundingBox"] \ + -anchor w +pack [label .config_t.hiresf.l -text "Uncheck to prevent clipping"] \ + -anchor w + +pack [checkbutton .config_t.hiresf.c \ + -text "Use hires boundingbox if possible"] -anchor w +.config_t.hiresf.c configure \ + -variable settings(ignore_hires_bb) -onvalue 0 -offvalue 1 + +spacing .config_t + +# buttons for closing the configuration screen + +pack [frame .config_t.buttonsf] -fill x +packb [button .config_t.buttonsf.done -text "Done" -command putsettings] \ + -side right +packb [button .config_t.buttonsf.cancel -text "Cancel" \ + -command cancelsettings] -side right + +wm transient .config_t +wm overrideredirect .config_t +wm withdraw .config_t + +proc edit_settings {} { + wm deiconify .config_t + raise .config_t + grab set .config_t +} + +# store new settings +proc putsettings {} { + if {$::classic_unix} { + wm withdraw .config_t.viewf.pdf.lf + wm withdraw .config_t.viewf.ps.lf + } + wm withdraw .config_t + grab release .config_t + write_settings +} + +proc write_settings {} { + set s "" + foreach el [array names ::settings] { + set s "$s$el=$::settings($el)\n" + } + #puts "\nsettings for epspdf.rb\n$s" + if [catch {exec $::ruby $::epspdf_rb --gui=config_r << $s} result] { + error "Epspdf configuration error: $result" + } +} + +proc cancelsettings {} { + if {$::classic_unix} { + wm withdraw .config_t.viewf.pdf.lf + wm withdraw .config_t.viewf.ps.lf + } + wm withdraw .config_t + grab release .config_t + # re-read config file / reg entries + getsettings +} + +### main screen ############################# + +proc show_w {w} { + wm deiconify $w + raise $w +} + +# buttons to call up configure-, log- and help screens + +pack [frame .topf] -fill x +packb [button .topf.config_t -text "Configure" \ + -command edit_settings] -side left +packb [button .topf.help_t -text "Help" \ + -command {show_w .help_t}] -side right +packb [button .topf.logb -text "Show log" -command {show_w .log_t}] \ + -side right -anchor w + +# file info in grid layout + +packf [frame .infof -relief sunken -border 1] -fill x +grid [label .infof.dir_label -text "Directory" -anchor w] \ + -row 1 -column 1 -sticky w +grid [label .infof.dir_value -textvariable gfile(dir) -anchor w] \ + -row 1 -column 2 -sticky w + +grid [label .infof.name_label -text "File" -anchor w] \ + -row 2 -column 1 -sticky w +grid [label .infof.name_value -textvariable gfile(name) -anchor w] \ + -row 2 -column 2 -sticky w + +grid [label .infof.type_label -text "Type" -anchor w] \ + -row 3 -column 1 -sticky w +grid [label .infof.type_value -textvariable gfile(type) -anchor w] \ + -row 3 -column 2 -sticky w + +grid [label .infof.npages_label -text "Pages" -anchor w] \ + -row 4 -column 1 -sticky w +grid [label .infof.npages_value -textvariable gfile(npages) -anchor w] \ + -row 4 -column 2 -sticky w + +grid columnconfigure .infof 1 -weight 1 -pad 2 +grid columnconfigure .infof 2 -weight 3 -pad 2 + +spacing . + +# conversion options + +pack [frame .optsf] -fill x + +# grayscaling +pack [frame .optsf.gray] -side left -anchor nw +pack [label .optsf.gray.l -text "Grayscaling"] -anchor w +pack [radiobutton .optsf.gray.off -text "No color conversion" \ + -variable options(gray) -value "color"] -anchor w +pack [radiobutton .optsf.gray.gray -text "Try to grayscale" \ + -variable options(gray) -value "gray"] -anchor w +pack [radiobutton .optsf.gray.gRAY -text "Try harder to grayscale" \ + -variable options(gray) -value "gRAY"] -anchor w + +# output format +pack [label .optsf.format] -side right -anchor ne +pack [label .optsf.format.l -text "Output format"] -anchor w +pack [radiobutton .optsf.format.pdf -text "pdf" -command set_widget_states \ + -variable options(format) -value "pdf"] -anchor w +pack [radiobutton .optsf.format.eps -text "eps" -command set_widget_states \ + -variable options(format) -value "eps"] -anchor w +pack [radiobutton .optsf.format.ps -text "ps" -command set_widget_states \ + -variable options(format) -value "ps"] -anchor w + +spacing . + +# boundingbox +pack [checkbutton .bbox -text "Compute tight boundingbox" \ + -variable options(bbox) -command set_widget_states] -anchor w + +# page selection +pack [frame .pagesf] -fill x +pack [radiobutton .pagesf.all -text "Convert all pages" \ + -variable options(pages) -value "all" -command set_widget_states] \ + -side left +pack [radiobutton .pagesf.single -text "Page:" \ + -variable options(pages) -value "single" -command set_widget_states] \ + -side left +pack [entry .pagesf.e -width 6 -textvariable ::options(page)] -side left +#.pagesf.e configure -vcmd {page_valid %W} -validate focusout \ +# -invcmd "focusAndFlash %W [.pagesf.e cget -fg] [.pagesf.e cget -bg]" +.pagesf.e configure -vcmd {page_valid %W} -validate focusout \ + -invcmd "see_red %W" + +spacing . + +# temp files +pack [checkbutton .clean -text "Remove temp files" \ + -variable options(clean)] -anchor w + +proc focusAndFlash {w fg bg {count 9}} { + focus $w + if {$count<1} { + $w configure -foreground $fg -background $bg + } else { + if {$count%2} { + $w configure -foreground $bg -background $fg + } else { + $w configure -foreground $fg -background $bg + } + after 200 [list focusAndFlash $w $fg $bg [expr {$count-1}]] + } +} + +proc see_red {w} { + focus $w + set orig [$w cget -bg] + $w configure -bg red + update idletasks + after 1000 + $w configure -bg $orig + update idletasks +} + +proc page_valid {w} { + # w entry widget + set p [$w get] + set isvalid 1 + #puts "check pageno $p" + if {! [string is integer $p] || $p<=0} { + set isvalid 0 + } elseif {$::gfile(npages) ne "" && [scan $p "%d"] > $::gfile(npages)} { + set isvalid 0 + } + return $isvalid +} + +# end conversion options + +pack [label .status] -side bottom -anchor w -fill x + +# main buttons + +pack [frame .bottomf] -side bottom -fill x +packb [button .bottomf.view -text "View" -command view] -side left +packb [button .bottomf.open -text "Open" -command openDialog] \ + -side left -padx 2 +packb [button .bottomf.convert -text "Convert and save..." \ + -command saveDialog] -side left -padx 2 +packb [button .bottomf.done -text "Done" -command exit] -side right + +proc view {} { + if {! [viewable]} { + tk_messageBox -icon warning -type ok \ + -message "No viewer for $::gfile(path)" + return + } + if {$::tcl_platform(os) eq "Darwin"} { + catch {exec open $::gfile(path) &} + } elseif {$::tcl_platform(platform) ne "unix"} { + # use shortname to sidestep quoting problems + catch {exec cmd /x /c start [file attributes $::gfile(path) -shortname]} + } else { + if {$::gfile(type) eq "pdf"} { + catch {exec $::settings(pdf_viewer) $::gfile(path) &} + } elseif {$::gfile(type) ne "other" && $::gfile(type) ne ""} { + catch {exec $::settings(ps_viewer) $::gfile(path) &} + } + } +} + +proc openDialog {} { + set types { + {"Encapsulated PostScript" {.eps .epi .epsi}} + {"General PostScript" {.ps .prn}} + {"Pdf" {.pdf}} + {"All files" *} + } + if {[file isdirectory $::gfile(dir)]} { + set try [tk_getOpenFile -filetypes $types -initialdir $::gfile(dir)] + } else { + set try [tk_getOpenFile -filetypes $types] + } + if {$try != ""} { + set ::gfile(path) [file normalize $try] + set ::gfile(dir) [file dirname $::gfile(path)] + set ::gfile(name) [file tail $::gfile(path)] + if {[run_epspdf result -i $::gfile(path)]} { + # parse output + regexp { is (\w+)(?: with (\d+) pages)?[\r\n]*$} $result \ + mtc ::gfile(type) ::gfile(npages) + if {[regexp {^eps} $::gfile(type)]} {set ::gfile(npages) 1} + } + set ::settings(defaultDir) $::gfile(dir) + putsettings + } + set_widget_states +} + +proc saveDialog {} { + if {$::options(format) eq "pdf"} { + set types {{"Pdf" {.pdf}}} + } elseif {$::options(format) eq "ps"} { + set types {{"PostScript" {.ps}}} + } elseif {$::options(format) eq "eps"} { + set types {{"Encapsulated PostScript" {.eps}}} + } + set try [tk_getSaveFile -filetypes $types -initialdir $::gfile(dir)] + if {$try != ""} { + # fix extension + set try [file normalize $try] + set idot [string last "." [file tail $try]] + if {$idot == -1} { + append try ".$::options(format)" + } else { + # don't bother checking whether the extension is already correct + set try [string range $try 0 [string last "." $try]] + append try $::options(format) + } + # epspdf can read persistent options from configuration. + # only options from the options array need to be converted to parameters. + set cmd [list run_epspdf result] + if {$::options(gray) eq "gray"} { + lappend cmd "-g" + } elseif {$::options(gray) eq "gRAY"} { + lappend cmd "-G" + } + if {$::options(bbox)} {lappend cmd "-b"} + if {! $::options(clean)} {lappend cmd "-d"} + if {$::options(pages) eq "single"} { + if {$::options(page) eq ""} {set ::options(page) 1} + lappend cmd "-p" $::options(page) + } + lappend cmd $::gfile(path) + lappend cmd $try + # $cmd/run_epspdf never bombs, but returns 1 (success) or 0 (fail) + .status configure -text "Working..." + foreach b {view open convert done} { + .bottomf.$b configure -state disabled + } + update idletasks; # force immediate redisplay main window + + if {[eval $cmd]} { + # if failure, there has already been an error message + set ::gfile(path) $try + set ::gfile(dir) [file dirname $try] + set ::gfile(type) $::options(format) + set ::gfile(name) [file tail $try] + set ::gfile(path) [file normalize $try] + set ::gfile(dir) [file dirname $::gfile(path)] + set ::gfile(name) [file tail $::gfile(path)] + # parse result output + regexp { is (\w+)(?: with (\d+) pages)?[\r\n]*$} \ + [string range $result [string last "File type of" $result] end] \ + mtc ::gfile(type) ::gfile(npages) + if {$::gfile(type) eq "eps"} {set ::gfile(npages) 1} + set ::settings(defaultDir) $::gfile(dir) + putsettings + } + .status configure -text "" + foreach b {view open convert done} { + .bottomf.$b configure -state normal + } + set_widget_states + } +} + +proc set_widget_states {} { + # states (normal/disabled) for various widgets. + # their values should already be mutually consistent. + # widgets concerned: + # view / save + # output format / bbox / single page / page no. + + # view + if {[viewable]} { + .bottomf.view configure -state normal + } else { + .bottomf.view configure -state disabled + } + + # convert + if {$::gfile(path) ne "" && [file exists $::gfile(path)] && \ + $::gfile(type) ne "other"} { + .bottomf.convert configure -state normal + } else { + .bottomf.convert configure -state disabled + } + + # type + if {[regexp {ps|pdf} $::gfile(type)]} { + foreach f {pdf eps ps} {.optsf.format.$f configure -state normal} + } else { + foreach f {pdf eps ps} {.optsf.format.$f configure -state disabled} + } + + # pages and page + foreach f {all single} {.pagesf.$f configure -state normal} + if {$::options(format) eq "eps"} { + .pagesf.all configure -state disabled + set ::options(pages) "single" + } + if {$::options(format) eq "ps"} { + .pagesf.single configure -state disabled + set ::options(pages) "all" + } + if {$::options(pages) eq "all"} { + .pagesf.e configure -state disabled + } else { + .pagesf.e configure -state normal + } + + # boundingbox + if {$::options(format) eq "eps"} { + .bbox configure -state normal + } elseif {$::options(pages) eq "all"} { + .bbox configure -state disabled + set ::options(bbox) 0 + } else { + .bbox configure -state normal + } +} + +set_widget_states |