summaryrefslogtreecommitdiff
path: root/Master/tlpkg/installer
diff options
context:
space:
mode:
authorSiep Kroonenberg <siepo@cybercomm.nl>2011-03-23 17:48:43 +0000
committerSiep Kroonenberg <siepo@cybercomm.nl>2011-03-23 17:48:43 +0000
commitaf239484eb8ca0c0bec8804f054f7e482b9d6fe6 (patch)
tree74e4b1c2a606563741bbbecefb1d10fce82bf4a0 /Master/tlpkg/installer
parent161cc5508f7aa14ffe0713f3d3e4979b551ca6c4 (diff)
Experimental installer with in-place and revised portable options
git-svn-id: svn://tug.org/texlive/trunk@21811 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/tlpkg/installer')
-rw-r--r--Master/tlpkg/installer/install-menu-perltk-new.pl1054
-rwxr-xr-xMaster/tlpkg/installer/install-menu-text-new.pl1070
2 files changed, 2124 insertions, 0 deletions
diff --git a/Master/tlpkg/installer/install-menu-perltk-new.pl b/Master/tlpkg/installer/install-menu-perltk-new.pl
new file mode 100644
index 00000000000..6cb806fbb92
--- /dev/null
+++ b/Master/tlpkg/installer/install-menu-perltk-new.pl
@@ -0,0 +1,1054 @@
+#!/usr/bin/env perl
+# $Id: install-menu-perltk.pl 20268 2010-10-31 07:26:14Z preining $
+#
+# Copyright 2008, 2009, 2010 Norbert Preining
+# Copyright 2008 Reinhard Kotucha
+# This file is licensed under the GNU General Public License version 2
+# or any later version.
+#
+# TODO:
+# - make the fancy selector the default, at least on unix
+# - for w32 find out the necessary files for the fancy selector and move
+# them to the installer perl package
+
+use strict;
+$^W = 1;
+
+my $svnrev = '$Revision: 20268 $';
+$svnrev =~ m/: ([0-9]+) /;
+$::menurevision = $1;
+
+require Tk;
+require Tk::Dialog;
+require Tk::DialogBox;
+require Tk::PNG;
+require Tk::ROText;
+require Tk::ProgressBar;
+require Tk::BrowseEntry;
+
+if ($::alternative_selector) {
+ require Tk::DirTree;
+}
+
+use utf8;
+no utf8;
+
+our %vars;
+our $tlpdb;
+our @collections_std;
+our @collections_lang;
+our @collections_lang_doc;
+our $texlive_release;
+
+our $MENU_INSTALL = 0;
+our $MENU_ABORT = 1;
+our $MENU_QUIT = 2;
+our $MENU_ALREADYDONE = 3;
+
+my $return = $MENU_INSTALL;
+
+our $LANG;
+our %TRANS;
+require("TeXLive/trans.pl");
+
+$::fileassocdesc[0] = __("None");
+$::fileassocdesc[1] = __("Only new");
+$::fileassocdesc[2] = __("All");
+
+$::letterdesc[0] = __('A4');
+$::letterdesc[1] = __('letter');
+
+my $mw;
+my $subframe;
+my $mainwindow;
+my $bintextbutton;
+my $schemebutton;
+my $tmflocalbutton;
+my $tmfsysvarbutton;
+my $tmfsysconfigbutton;
+my $tmfhomebutton;
+my $pathbutton;
+my $deskintbutton;
+my $assocbutton;
+my $adminbutton;
+my $collectionstext;
+my $texmflocaltext;
+my $texmfsysvartext;
+my $texmfsysconfigtext;
+my $texmfhometext;
+my $texdirtext;
+my $langcoltext;
+my $optletterstate;
+my $optfmtstate;
+my $optsrcstate;
+my $optdocstate;
+my $portableyesno = ( $vars{'portable'} ? __("Yes") : __("No") );
+my $letteryesno = $::letterdesc[$vars{'option_letter'}];
+my $fmtyesno = ( $vars{'option_fmt'} ? __("Yes") : __("No") );
+my $srcyesno = ( $vars{'option_src'} ? __("Yes") : __("No") );
+my $deskintyesno = ( $vars{'option_desktop_integration'} ? __("Yes") : __("No") );
+my $pathadjyesno = ( $vars{'option_path'} ? __("Yes") : __("No") );
+my $fileassocyesno = $::fileassocdesc[$vars{'option_file_assocs'}];
+my $editoryesno = ( $vars{'collection-texworks'} ? __("Yes") : __("No") );
+my $adminallyesno = ( $vars{'option_w32_multi_user'} ? __("Yes") : __("No") );
+my $docyesno = ( $vars{'option_doc'} ? __("Yes") : __("No") );
+my $restrictedyesno = ( $vars{'option_write18_restricted'} ? __("Yes") : __("No") );
+
+$::run_menu = \&run_menu_perltk;
+
+
+####################################################################
+# From here on only function definitions
+# ##################################################################
+
+
+sub menu_abort {
+ $return = $MENU_ABORT;
+ $mainwindow->destroy;
+}
+
+sub setup_hooks_perltk {
+ @::info_hook = ();
+ push @::info_hook,
+ sub {
+ return unless defined $mainwindow;
+ update_status(join(" ",@_));
+ $mainwindow->update;
+ };
+ push @::warn_hook,
+ sub {
+ return unless defined $mainwindow ;
+ update_status(join(" ",@_));
+ $mainwindow->update;
+ };
+ @::install_packages_hook = ();
+ push @::install_packages_hook, \&update_progressbar;
+ push @::install_packages_hook,
+ sub {
+ return unless defined $mainwindow;
+ return unless defined $::sww;
+ $mainwindow->update;
+ $::sww->update;
+ };
+}
+
+sub update_status {
+ my ($p) = @_;
+ return unless defined $::progressw;
+ $::progressw->insert("end", "$p");
+ $::progressw->see("end");
+}
+sub update_progressbar {
+ my ($n,$total) = @_;
+ return unless defined $::progress;
+ if (defined($n) && defined($total)) {
+ $::progress->value(int($n*100/$total));
+ }
+}
+
+
+sub run_menu_perltk {
+ calc_depends();
+ $mainwindow = Tk::MainWindow->new;
+ $mainwindow->protocol('WM_DELETE_WINDOW' => \&menu_abort);
+ setup_hooks_perltk();
+
+ if (!win32()) {
+ require Tk::Pane;
+ $subframe = $mainwindow->Scrolled("Frame", -scrollbars => "oe");
+ } else {
+ $subframe = $mainwindow->Frame;
+ }
+ $mw = $subframe->Frame;
+
+ # image frame on the left
+ my $fl = $mw->Frame(-background => "#0078b8");
+ my $img = $fl->Photo(-format => 'png', -file => "$::installerdir/tlpkg/installer/texlive.png");
+ $fl->Label(-image => $img, -background => "#0078b8")->pack(-expand => 1, -fill => "y");
+ $fl->Label(-text => "v$::installerrevision/$::menurevision", -background => "#0078b8")->pack;
+
+ # data frame on the right
+ my $fr = $mw->Frame;
+ $fl->pack(-side => 'left', -expand => 1, -fill => "y");
+ $fr->pack(-side => 'right');
+
+
+ my $row = 1;
+ $fr->Label(-text => __("TeX Live %s Installation", $TeXLive::TLConfig::ReleaseYear))->grid(-row => $row, -column => 1, -columnspan => 3);
+
+ if (!$vars{'in_place'}) {
+
+ $row++;
+ $fr->Label(-text => "------- " . __("Basic Information") . " -------")->grid(-row => $row, -column => 1, -columnspan => 3);
+
+ # binary system line
+ if (!win32()) {
+ $row++;
+ $fr->Label(-text => __('Binary system(s)'), -anchor => 'w')->grid(-row => $row, -column => 1, -sticky => 'w');
+ $bintextbutton = $fr->Label(-anchor => 'w');
+ $bintextbutton->grid(-row => $row, -column => 2, -padx => "2m");
+ $fr->Button(-text => __("Change"), -command => sub { menu_select_binsystems(); })->grid(-row => $row, -column => 3, -sticky => "ew", -padx => "2m");
+ }
+
+ $row++;
+
+ # scheme line
+ $fr->Label(-text => __('Selected scheme'), -anchor => 'w')->grid(-row => $row, -column => 1, -sticky => 'w');
+ $schemebutton = $fr->Label(-anchor => 'w');
+ $schemebutton->grid(-row => $row, -column => 2, -padx => "2m");
+ $fr->Button(-text => __("Change"), -command => sub { menu_select_scheme(); })->grid(-row => $row, -column => 3, -sticky => "ew", -padx => "2m");
+
+ $row++;
+
+ # further customization
+ $fr->Label(-text => "------- " . __("Further Customization") . " -------")->grid(-row => $row, -column => 1,-columnspan => 3);
+
+ $row++;
+ # standard collection line
+ $fr->Label(-text => __('Standard collections'), -anchor => 'w')->grid(-row => $row, -column => 1, -sticky => 'w');
+ $fr->Button(-text => __("Change"), -command => sub { menu_select_standard_collections(); })->grid(-row => $row, -column => 3, -sticky => "ew", -padx => "2m");
+
+ $row++;
+ # lang collection line
+ $fr->Label(-text => __('Language collections'), -anchor => 'w')->grid(-row => $row, -column => 1, -sticky => 'w');
+ $langcoltext = $fr->Label(-anchor => 'w')->grid(-row => $row, -column => 2, -padx => "2m");
+ $fr->Button( -text => __("Change"), -command => sub { menu_select_lang_collections(); })->grid(-row => $row, -column => 3, -sticky => "ew", -padx => "2m");
+
+ $row++;
+ $collectionstext = $fr->Label();
+ $collectionstext->grid(-row => $row, -column => 1, -columnspan => 3);
+ }
+
+ $row++;
+ # further customization
+ $fr->Label(-text => "------- " . __("Directory setup") . " -------")->grid(-row => $row, -column => 1, -columnspan => 3);
+
+ $row++;
+ $fr->Label(-text => __('Portable setup'), -anchor => 'w')->grid(-row => $row, -column => 1, -sticky => 'w');
+ $fr->Label(-anchor => 'w', -textvariable => \$portableyesno)->grid(-row => $row, -column => 2, -padx => "2m");
+ $fr->Button(-text => __("Toggle"), -command => sub { toggle_portable(); })->grid(-row => $row, -column => 3, -sticky => "ew", -padx => "2m");
+
+ $row++;
+ # texdir line
+ $fr->Label(-text => __('TEXDIR (the main TeX directory)'), -anchor => 'w')->grid(-row => $row, -column => 1, -sticky => 'w');
+ $texdirtext = $fr->Label(-anchor => 'w')->grid(-row => $row, -column => 2, -padx => "2m");
+ if (!$vars{'in_place'}) {
+ if ($::alternative_selector) {
+ $fr->Button(-text => __("Change"), -command => sub { menu_edit_texdir("TEXDIR"); })->grid(-row => $row, -column => 3, -sticky => "ew", -padx => "2m");
+ } else {
+ $fr->Button(-text => __("Change"), -command => sub { menu_edit_vars_value("TEXDIR"); })->grid(-row => $row, -column => 3, -sticky => "ew", -padx => "2m");
+ }
+ }
+
+
+ $row++;
+ # texmflocal line
+ $fr->Label(-text => __('TEXMFLOCAL (directory for site-wide local files)'), -anchor => 'w')->grid(-row => $row, -column => 1, -sticky => 'w');
+ $texmflocaltext = $fr->Label(-anchor => 'w')->grid(-row => $row, -column => 2, -padx => "2m");
+ $tmflocalbutton = $fr->Button(-text => __("Change"), -command => sub { menu_edit_vars_value("TEXMFLOCAL"); });
+ $tmflocalbutton -> grid(-row => $row, -column => 3, -sticky => "ew", -padx => "2m");
+
+ $row++;
+ # texmfsysvar line
+ $fr->Label(-text => __('TEXMFSYSVAR (directory for autogenerated data)'), -anchor => 'w')->grid(-row => $row, -column => 1, -sticky => 'w');
+ $texmfsysvartext = $fr->Label(-anchor => 'w')->grid(-row => $row, -column => 2, -padx => "2m");
+ $tmfsysvarbutton = $fr->Button(-text => __("Change"), -command => sub { menu_edit_vars_value("TEXMFSYSVAR"); });
+ $tmfsysvarbutton->grid(-row => $row, -column => 3, -sticky => "ew", -padx => "2m");
+
+ $row++;
+ # texmfsysconfig line
+ $fr->Label(-text => __('TEXMFSYSCONFIG (directory for local config)'), -anchor => 'w')->grid(-row => $row, -column => 1, -sticky => 'w');
+ $texmfsysconfigtext = $fr->Label(-anchor => 'w')->grid(-row => $row, -column => 2, -padx => "2m");
+ $tmfsysconfigbutton = $fr->Button(-text => __("Change"), -command => sub { menu_edit_vars_value("TEXMFSYSCONFIG"); });
+ $tmfsysconfigbutton->grid(-row => $row, -column => 3, -sticky => "ew", -padx => "2m");
+
+ $row++;
+ # texmfhome line
+ $fr->Label(-text => __('TEXMFHOME (directory for user-specific files)'), -anchor => 'w')->grid(-row => $row, -column => 1, -sticky => 'w');
+ $texmfhometext = $fr->Label(-anchor => 'w')->grid(-row => $row, -column => 2, -padx => "2m");
+ $tmfhomebutton = $fr->Button(-text => __("Change"), -command => sub { menu_edit_vars_value("TEXMFHOME"); });
+ $tmfhomebutton->grid(-row => $row, -column => 3, -sticky => "ew", -padx => "2m");
+
+ if ($vars{'portable'}) {
+ for my $b ($tmflocalbutton, $tmfsysvarbutton, $tmfsysconfigbutton, $tmfhomebutton) {
+ $b->configure(-state => 'disabled')
+ }
+ }
+
+ $row++;
+ # Options
+ $fr->Label(-text => "------- " . __("Options") . " -------")->grid(-row => $row, -column => 1, -columnspan => 3);
+
+ $row++;
+ # optpaper
+ $fr->Label(-text => __('Default paper size'), -anchor => 'w')->grid(-row => $row, -column => 1, -sticky => 'w');
+ $fr->Label(-anchor => 'w', -textvariable => \$letteryesno)->grid(-row => $row, -column => 2, -padx => "2m");
+ $fr->Button(-text => __("Toggle"), -command => sub { toggle_and_set_opt_variable(\$vars{'option_letter'}, \$letteryesno, \@::letterdesc); })->grid(-row => $row, -column => 3, -sticky => "ew", -padx => "2m");
+
+ $row++;
+ $fr->Label(-text => __('Allow execution of restricted list of programs via \write18'), -anchor => 'w')->grid(-row => $row, -column => 1, -sticky => 'w');
+ $fr->Label(-anchor => 'w', -textvariable => \$restrictedyesno)->grid(-row => $row, -column => 2, -padx => "2m");
+ $fr->Button(-text => __("Toggle"), -command => sub { toggle_and_set_opt_variable(\$vars{'option_write18_restricted'}, \$restrictedyesno); })->grid(-row => $row, -column => 3, -sticky => "ew", -padx => "2m");
+
+ $row++;
+ $fr->Label(-text => __('Create all format files'), -anchor => 'w')->grid(-row => $row, -column => 1, -sticky => 'w');
+ $fr->Label(-anchor => 'w', -textvariable => \$fmtyesno)->grid(-row => $row, -column => 2, -padx => "2m");
+ $fr->Button(-text => __("Toggle"), -command => sub { toggle_and_set_opt_variable(\$vars{'option_fmt'}, \$fmtyesno); })->grid(-row => $row, -column => 3, -sticky => "ew", -padx => "2m");
+
+ if ($vars{'doc_splitting_supported'} and !$vars{'in_place'}) {
+ $row++;
+ $fr->Label(-text => __('Install font/macro doc tree'), -anchor => 'w')->grid(-row => $row, -column => 1, -sticky => 'w');
+ $fr->Label(-anchor => 'w', -textvariable => \$docyesno)->grid(-row => $row, -column => 2, -padx => "2m");
+ $fr->Button(-text => __("Toggle"), -command => sub { toggle_and_set_opt_variable(\$vars{'option_doc'}, \$docyesno); })->grid(-row => $row, -column => 3, -sticky => "ew", -padx => "2m");
+ }
+
+ if ($vars{'src_splitting_supported'} and !$vars{'in_place'}) {
+ $row++;
+ $fr->Label(-text => __('Install font/macro source tree'), -anchor => 'w')->grid(-row => $row, -column => 1, -sticky => 'w');
+ $fr->Label(-anchor => 'w', -textvariable => \$srcyesno)->grid(-row => $row, -column => 2, -padx => "2m");
+ $fr->Button(-text => __("Toggle"), -command => sub { toggle_and_set_opt_variable(\$vars{'option_src'}, \$srcyesno); })->grid(-row => $row, -column => 3, -sticky => "ew", -padx => "2m");
+ }
+
+ $row++;
+ $fr->Label(-text => (win32()) ? __('Adjust PATH setting in registry') :
+ __('Create symlinks in system directories'),
+ -anchor => 'w')->grid(-row => $row, -column => 1, -sticky => 'w');
+ $fr->Label(-anchor => 'w', -textvariable => \$pathadjyesno)->grid(-row => $row, -column => 2, -padx => "2m");
+ if (unix()) {
+ $pathbutton = $fr->Button(-text => __("Change"), -command => sub { menu_select_symlink(); });
+ } else {
+ $pathbutton = $fr->Button(-text => __("Toggle"), -command => sub { toggle_and_set_opt_variable(\$vars{'option_path'}, \$pathadjyesno); });
+ }
+ $pathbutton->grid(-row => $row, -column => 3, -sticky => "ew", -padx => "2m");
+
+ if ($::opt_all_options || win32()) {
+ $row++;
+ $fr->Label(-text => __('Add shortcuts to menu and desktop'), -anchor => 'w')->grid(-row => $row, -column => 1, -sticky => 'w');
+ $fr->Label(-anchor => 'w', -textvariable => \$deskintyesno)->grid(-row => $row, -column => 2, -padx => "2m");
+ $deskintbutton = $fr->Button(-text => __("Toggle"), -command => sub { toggle_and_set_opt_variable(\$vars{'option_desktop_integration'}, \$deskintyesno); });
+ $deskintbutton->grid(-row => $row, -column => 3, -sticky => "ew", -padx => "2m");
+
+ $row++;
+ $fr->Label(-text => __('Change file associations'), -anchor => 'w')->grid(-row => $row, -column => 1, -sticky => 'w');
+ $fr->Label(-anchor => 'w', -textvariable => \$fileassocyesno)->grid(-row => $row, -column => 2, -padx => "2m");
+ $assocbutton = $fr->Button(-text => __("Change"), -command => sub { menu_edit_file_assocs(); });
+ $assocbutton->grid(-row => $row, -column => 3, -sticky => "ew", -padx => "2m");
+
+ if ($::opt_all_options || admin()) {
+ $row++;
+ $fr->Label(-text => __('Installation for all users'), -anchor => 'w')->grid(-row => $row, -column => 1, -sticky => 'w');
+ $fr->Label(-anchor => 'w', -textvariable => \$adminallyesno)->grid(-row => $row, -column => 2, -padx => "2m");
+ $adminbutton = $fr->Button(-text => __("Toggle"), -command => sub { toggle_and_set_opt_variable(\$vars{'option_w32_multi_user'}, \$adminallyesno); });
+ $adminbutton->grid(-row => $row, -column => 3, -sticky => "ew", -padx => "2m");
+ }
+
+ $row++;
+ $fr->Label(-text => __('Install TeXworks front end'), -anchor => 'w')->grid(-row => $row, -column => 1, -sticky => 'w');
+ $fr->Label(-anchor => 'w', -textvariable => \$editoryesno)->grid(-row => $row, -column => 2, -padx => "2m");
+ if (!$vars{'in_place'}) {
+ $fr->Button(-text => __("Toggle"), -command => sub { toggle_and_set_opt_variable(\$vars{'collection-texworks'}, \$editoryesno); })->grid(-row => $row, -column => 3, -sticky => "ew", -padx => "2m");
+ }
+ }
+ if ($vars{'portable'}) {
+ for $b ($pathbutton, $deskintbutton, $assocbutton, $adminbutton) {
+ $b->configure(-state => 'disabled') if $b;
+ }
+ }
+
+ # install/cancel buttons
+ my $f3 = $fr->Frame;
+ $f3->Button(
+ -text => __("Install TeX Live"),
+ -command => sub { installation_window(); }
+ )->pack(-side => 'left', -padx => "2m", -pady => "2m")->focus();
+ my $quitbutton = $f3->Button(
+ -text => __("Quit"),
+ -command => \&menu_abort,
+ )->pack(-side => 'right', -padx => "2m", -pady => "2m");
+ $mw->bind('<Escape>', [ $quitbutton, 'Invoke' ]);
+ #my $wizardbutton = $f3->Button(
+ # -text => __("Wizard"),
+ # -command => sub {
+ # $mainwindow->destroy;
+ # require("installer/install-menu-wizard.pl");
+ # setup_hooks_wizard();
+ # $return = run_menu_wizard();
+ # })->pack(-side => 'right', -padx => "2m", -pady => "2m");
+ $row++;
+ $f3->grid(-row => $row, -column => 1, -columnspan => 3);
+ menu_update_texts();
+ $fr->gridColumnconfigure(2, -minsize => 300);
+ $mw->pack(-expand => 1, -fill => "both");
+ $mw->update;
+ my $rh = $mw->reqheight;
+ my $rw = $mw->reqwidth;
+ my $maxheight = $mainwindow->screenheight() - 20;
+ debug("Requested height: $rh, requested width: $rw, max height: $maxheight\n");
+ if ($rh > $maxheight) {
+ $rh = $maxheight;
+ $rw += 20; # for the scrollbar = =
+ }
+ $subframe->configure(-height => $rh, -width=>$rw);
+ $subframe->pack(-expand => 1, -fill => "both");
+ $mainwindow->configure(-height => $rh, -width=>$rw);
+ #$mw->pack(-expand => 1, -fill => "both");
+ Tk::MainLoop();
+ return($return);
+}
+
+sub installation_window {
+ # create a progress bar window
+ $::sww = $mainwindow->Toplevel(-title => __("Installation process"),
+ -width => 400);
+ $::sww->transient($mainwindow);
+ $::sww->grab();
+ $::sww->Label(-text => __("Installation process"))->pack;
+ $::progressw = $::sww->Scrolled("ROText", -scrollbars => "e", -height => 16);
+ $::progressw->pack(-expand => 1, -fill => "both");
+ my $percent_done = 0;
+ $::progress = $::sww->ProgressBar(-variable => \$percent_done,
+ -width => 20, -length => 400, -from => 0, -to => 100, -blocks => 10,
+ -colors => [ 0, '#0078b8' ]);
+ $::progress->pack(-fill => "x");
+ my $f = $::sww->Frame;
+ my $b = $f->Button(-text => __("Cancel"),
+ -command => sub { $::sww->destroy; $mainwindow->destroy;
+ do_cleanup(); exit(1); }
+ )->pack(-pady => "2m");
+ $b->focus();
+ $f->pack;
+ do_installation();
+ $return = $MENU_ALREADYDONE;
+ my $t = __("See %s/index.html for links to documentation.\nThe TeX Live web site (http://tug.org/texlive/) contains any updates and corrections. TeX Live is a joint project of the TeX user groups around the world; please consider supporting it by joining the group best for you. The list of groups is available on the web at http://tug.org/usergroups.html.", $::vars{'TEXDIR'});
+ if (!win32()) {
+ $t .= "\n\n" . __("Add %s/texmf/doc/man to MANPATH.\nAdd %s/texmf/doc/info to INFOPATH.\nMost importantly, add %s/bin/%s\nto your PATH for current and future sessions.", $::vars{'TEXDIR'}, $::vars{'TEXDIR'}, $::vars{'TEXDIR'}, $::vars{'this_platform'});
+ }
+ if (@::WARNLINES) {
+ $t .= "\n\n" . __("There were some warnings during the installation process.\nHere is the list of warning messages:") . "\n";
+ $t .= join('', @::WARNLINES);
+ $t =~ s/\n\z//;
+ }
+
+ $t .= "\n\n" . __("Welcome to TeX Live!");
+ #$t =~ s/\\n/\n/g;
+ $::progressw->insert("end", "\n");
+ my $linechar = $::progressw->index("end");
+ $::progressw->markSet("finaltext", $linechar);
+ $::progressw->markGravity("finaltext", "left");
+ $::progressw->insert("end", "\n$t");
+ $::progressw->see("end");
+ $::progressw->tagAdd("centered", $linechar, "end");
+ $::progressw->tagConfigure("centered", -justify => "center");
+ $b->configure(-text => __("Finish"),
+ -command => sub { $mainwindow->destroy; });
+}
+
+# this sub will not be called if $vars{'in_place'}
+sub menu_edit_texdir {
+ my $key = shift;
+ our $addyear = 1;
+ our $addtexlive = 1;
+ my $val = $vars{$key};
+ our $currsel;
+ our $entry;
+ sub update_label {
+ my $t = $currsel;
+ $t .= "/texlive" if ($addtexlive);
+ $t .= "/$texlive_release" if ($addyear);
+ $entry->configure(-text => "$t");
+ }
+ my $hint_var;
+ if ($key ne 'TEXMFHOME') {
+ $hint_var = win32() ? $ENV{'USERPROFILE'} : $ENV{'HOME'};
+ } else {
+ $hint_var = win32() ? '%USERPROFILE%' : '$HOME';
+ }
+ if ($val =~ m!^(.*)/texlive/$texlive_release$!) {
+ $currsel = "$1";
+ $addyear = 1;
+ $addtexlive = 1;
+ } elsif ($val =~ m!^(.*)/$texlive_release$!) {
+ $currsel = "$1";
+ $addyear = 1;
+ $addtexlive = 0;
+ } elsif ($val =~ m!^(.*)/texlive$!) {
+ $currsel = "$1";
+ $addyear = 0;
+ $addtexlive = 1;
+ } else {
+ $addyear = 0;
+ $addtexlive = 0;
+ $currsel = $val;
+ }
+ my $sw = $mainwindow->Toplevel(-title => __("Change variable value"));
+ $sw->transient($mainwindow);
+ $sw->grab();
+ $sw->Label(-text => __("Enter path for %s (use ~ for %s)", $key, $hint_var))->pack(-padx => "2m", -pady => "2m");
+ $entry = $sw->Entry(-width => 60)->pack(-padx => "2m", -pady => "2m");
+ my $f = $sw->Frame;
+ my $c1 = $f->Checkbutton(-text => 'Add "texlive"', -variable => \$addtexlive,
+ -command => \&update_label);
+ my $c2 = $f->Checkbutton(-text => "Add \"$texlive_release\"", -variable => \$addyear,
+ -command => \&update_label);
+ my $foo = $sw->Scrolled("DirTree", -scrollbars => "osoe",
+ -browsecmd => sub { my ($d) = @_; $currsel = $d; update_label(); },
+ -directory => "$currsel");
+ my $ff = $sw->Frame;
+ my $ok = $ff->Button(-text => __("Ok"), -command => sub { $val = $entry->get; callback_edit_directories($key,$val); $sw->destroy; });
+ my $cancel = $ff->Button(-text => __("Cancel"), -command => sub { $sw->destroy; });
+ update_label();
+ $c1->pack(-side => "left", -padx => "2m", -pady => "2m");
+ $c2->pack(-side => "right", -padx => "2m", -pady => "2m");
+ $f->pack;
+ $foo->pack(-fill => "both", -expand => 1);
+ $ok->pack(-side => 'left' , -padx => "2m", -pady => "2m");
+ $cancel->pack(-side => 'right', -padx => "2m", -pady => "2m");
+ $ff->pack;
+ # bindings
+ $sw->bind('<Return>' => [ $ok, 'Invoke']);
+ $sw->bind('<Escape>' => [ $cancel, 'Invoke']);
+}
+
+sub menu_edit_vars_value {
+ my $key = shift;
+ my $sw = $mainwindow->Toplevel(-title => __("Change variable value"));
+ $sw->transient($mainwindow);
+ $sw->grab();
+ my $val = $vars{$key};
+ my $hint_var;
+ if ($key ne 'TEXMFHOME') {
+ $hint_var = win32() ? $ENV{'USERPROFILE'} : $ENV{'HOME'};
+ } else {
+ $hint_var = win32() ? '%USERPROFILE%' : '$HOME';
+ }
+ $sw->Label(-text => __("Enter path for %s (use ~ for %s)", $key, $hint_var))->pack(-padx => "2m", -pady => "2m");
+ my $entry = $sw->Entry(-text => native_slashify($val), -width => 60);
+ $entry->pack(-padx => "2m", -pady => "2m")->focus();
+ my $f = $sw->Frame;
+ my $okbutton = $f->Button(-text => __("Ok"),
+ -command => sub { $val = forward_slashify($entry->get); callback_edit_directories($key,$val) ; $sw->destroy })->pack(-side => 'left', -padx => "2m", -pady => "2m");
+ my $cancelbutton = $f->Button(-text => __("Cancel"),
+ -command => sub { $sw->destroy })->pack(-side => 'right', -padx => "2m", -pady => "2m");
+ $f->pack(-expand => 'x');
+ # bindings
+ $sw->bind('<Return>' => [ $okbutton, 'Invoke']);
+ $sw->bind('<Escape>' => [ $cancelbutton, 'Invoke']);
+}
+
+sub menu_edit_file_assocs {
+ my $sw = $mainwindow->Toplevel(-title => __('Change file associations'));
+ $sw->transient($mainwindow);
+ $sw->grab();
+ my $key = 'option_file_assocs';
+ my $var = $::fileassocdesc[$vars{$key}];
+ $sw->Label(-text => __("Change file associations"))->pack(-padx => "2m", -pady => "2m");
+ my $opt = $sw->BrowseEntry(-autolistwidth => 1,
+ -variable => \$var);
+ for my $i (0..2) {
+ $opt->insert("end", $::fileassocdesc[$i]);
+ }
+
+ $opt->pack(-padx => "2m", -pady => "2m")->focus();
+ my $f = $sw->Frame;
+ my $okbutton = $f->Button(-text => __("Ok"),
+ -command => sub {
+ my $idx;
+ if ($var eq $::fileassocdesc[0]) {
+ $idx = 0;
+ } elsif ($var eq $::fileassocdesc[1]) {
+ $idx = 1;
+ } elsif ($var eq $::fileassocdesc[2]) {
+ $idx = 2;
+ } else {
+ die "How that could happen!\n";
+ }
+ $vars{$key} = $idx;
+ $fileassocyesno = $::fileassocdesc[$idx];
+ $sw->destroy; })->pack(-side => "left", -padx => "2m", -pady => "2m");
+ my $cancelbutton = $f->Button(-text => __("Cancel"), -command => sub { $sw->destroy; })->pack(-side => "left", -padx => "2m", -pady => "2m");
+ $f->pack;
+ $sw->bind('<Return>', [ $okbutton, 'Invoke' ]);
+ $sw->bind('<Escape>', [ $cancelbutton, 'Invoke' ]);
+}
+
+
+sub menu_select_scheme {
+ my $sw = $mainwindow->Toplevel(-title => __('Selected scheme'));
+ $sw->transient($mainwindow);
+ $sw->grab();
+ my @schemes;
+ foreach my $pkg ($tlpdb->list_packages) {
+ my $tlpobj = $tlpdb->{'tlps'}{$pkg};
+ if ($tlpobj->category eq "Scheme") {
+ push @schemes, $pkg;
+ $vars{"$pkg"}=($vars{'selected_scheme'} eq $pkg)? 1:0;
+ }
+ }
+ @schemes=sort @schemes;
+ push @schemes, "scheme-custom";
+ my $selected = $vars{'selected_scheme'};
+ $sw->Label(-text => __("Selected scheme"))->pack(-padx => "2m", -pady => "2m");
+ my $f2 = $sw->Frame;
+ my $f2l = $f2->Frame;
+ my $f2r = $f2->Frame;
+ my $nrfh = $#schemes / 2;
+ my $i = 0;
+ foreach my $scheme (@schemes) {
+ my $desc;
+ if ($scheme ne "scheme-custom") {
+ my $tlpobj = $tlpdb->get_package("$scheme");
+ $desc = $tlpobj->shortdesc;
+ } else {
+ $desc = "custom selection of collections";
+ }
+ my $b;
+ if ($i < $nrfh) {
+ $b = $f2l->Radiobutton(-variable => \$selected, -value => $scheme,
+ -text => __($desc))->pack(-anchor => 'w');
+ } else {
+ $b = $f2r->Radiobutton(-variable => \$selected, -value => $scheme,
+ -text => __($desc))->pack(-anchor => 'w');
+ }
+ if ($selected eq $scheme) {
+ $b->focus();
+ }
+ $i++;
+ }
+ $f2l->pack(-side => 'left', -padx => "2m", -pady => "2m");
+ $f2r->pack(-side => 'right', -padx => "2m", -pady => "2m");
+ $f2->pack;
+ my $f3 = $sw->Frame;
+ my $okbutton = $f3->Button(-text => __("Ok"),
+ -command => sub { callback_select_scheme($selected) ; $sw->destroy })->pack(-side => 'left', -padx => "2m", -pady => "2m");
+ my $cancelbutton = $f3->Button(-text => __("Cancel"),
+ -command => sub { $sw->destroy })->pack(-side => 'left', -padx => "2m", -pady => "2m");
+ $f3->pack(-expand => 'x');
+ $sw->bind('<Return>' => [ $okbutton, 'Invoke']);
+ $sw->bind('<Escape>' => [ $cancelbutton, 'Invoke']);
+}
+
+sub menu_select_standard_collections {
+ my $sw = $mainwindow->Toplevel(-title => __('Standard collections'));
+ $sw->transient($mainwindow);
+ $sw->grab();
+ my $fb = $sw->Frame;
+ my $fc = $sw->Frame;
+ my $fd = $sw->Frame;
+ my $f1 = $fb->Frame;
+ my $f2 = $fb->Frame;
+ my %lvars = %vars;
+ $sw->Label(-text => __("Select the collections to be installed"))->pack(-padx => "2m", -pady => "2m");
+ my $halfcol = $#collections_std / 2;
+ my $i = 0;
+ foreach my $coll (sort @collections_std) {
+ my $tlpobj = $tlpdb->get_package("$coll");
+ if ($i < $halfcol) {
+ $f1->Checkbutton(-variable => \$lvars{$coll}, -text => __($tlpobj->shortdesc))->pack(-anchor => 'w');
+ } else {
+ $f2->Checkbutton(-variable => \$lvars{$coll}, -text => __($tlpobj->shortdesc))->pack(-anchor => 'w');
+ }
+ $i++;
+ }
+ $f1->pack(-side => 'left', -padx => "2m", -pady => "2m");
+ $f2->pack(-side => 'right', -padx => "2m", -pady => "2m");
+ $fb->pack(-padx => "2m", -pady => "2m");
+ $fc->pack();
+ $fc->Button(-text => __("Select All"),
+ -command => sub { select_collections(\%lvars, @collections_std) })->pack(-side => 'left', -padx => "2m", -pady => "2m")->focus();
+ $fc->Button(-text => __("Deselect All"),
+ -command => sub { deselect_collections(\%lvars, @collections_std) })->pack(-side => 'right', -padx => "2m", -pady => "2m");
+ $fd->pack(-expand => 'x', -padx => "2m", -pady => "2m");
+ my $okbutton = $fd->Button(-text => __("Ok"),
+ -command => sub {
+ # we call the update only if something has changed
+ my $changed = 0;
+ for my $k (keys %lvars) {
+ if ($vars{$k} ne $lvars{$k}) {
+ $changed = 1;
+ last;
+ }
+ }
+ if ($changed) {
+ %vars = %lvars;
+ callback_select_collection();
+ }
+ $sw->destroy;
+ })->pack(-side => 'left', -padx => "2m", -pady => "2m");
+ my $cancelbutton = $fd->Button(-text => __("Cancel"),
+ -command => sub { $sw->destroy })->pack(-side => 'right', -padx => "2m", -pady => "2m");
+ $sw->bind('<Return>' => [ $okbutton, 'Invoke']);
+ $sw->bind('<Escape>' => [ $cancelbutton, 'Invoke']);
+}
+
+sub menu_select_lang_collections {
+ my $sw = $mainwindow->Toplevel(-title => __('Language collections'));
+ $sw->transient($mainwindow);
+ $sw->grab();
+ my $f1 = $sw->Frame;
+ $f1->pack;
+ my $f1lang = $f1->Labelframe(-text => __("Select language support"));
+ my $f1doc = $f1->Labelframe(-text => __("Select language-specific documentation"));
+ $f1lang->pack(-side => 'left', -padx => "2m", -pady => "2m", -ipadx => "2m", -ipady => "2m");
+ $f1doc->pack(-side => 'right', -padx => "2m", -pady => "2m", -ipadx => "2m", -ipady => "2m", -expand => 1, -fill => "y");
+ my $f1langT = $f1lang->Frame; $f1langT->pack;
+ my $f1langL = $f1lang->Frame; $f1langL->pack;
+ my $f1langLa = $f1langL->Frame; $f1langLa->pack(-side => 'left');
+ my $f1langLb = $f1langL->Frame; $f1langLb->pack(-side => 'right');
+ my $langh = $#collections_lang / 2;
+ my $i = 0;
+ my %lvars = %vars;
+ foreach my $coll (sort @collections_lang) {
+ my $tlpobj = $tlpdb->get_package("$coll");
+ if ($i < $langh) {
+ $f1langLa->Checkbutton(-variable => \$lvars{$coll}, -text => __($tlpobj->shortdesc))->pack(-anchor => 'w');
+ } else {
+ $f1langLb->Checkbutton(-variable => \$lvars{$coll}, -text => __($tlpobj->shortdesc))->pack(-anchor => 'w');
+ }
+ $i++;
+ }
+ my $f1langB = $f1lang->Frame;
+ $f1langB->pack(-expand => 'x');
+ $f1langB->Button(-text => __("Select All"),
+ -command => sub { select_collections(\%lvars, @collections_lang) })->pack(-side => 'left', -padx => "2m", -pady => "2m")->focus();
+ $f1langB->Button(-text => __("Deselect All"),
+ -command => sub { deselect_collections(\%lvars, @collections_lang) })->pack(-side => 'right', -padx => "2m", -pady => "2m");
+
+ my $f1docT = $f1doc->Frame; $f1docT->pack;
+ my $f1docL = $f1doc->Frame; $f1docL->pack;
+ my $f1docLa = $f1docL->Frame; $f1docLa->pack(-side => 'left');
+ my $f1docLb = $f1docL->Frame; $f1docLb->pack(-side => 'right');
+ my $doch = $#collections_lang_doc / 2;
+ $i = 0;
+ foreach my $coll (sort @collections_lang_doc) {
+ my $tlpobj = $tlpdb->get_package("$coll");
+ if ($i < $doch) {
+ $f1docLa->Checkbutton(-variable => \$lvars{$coll}, -text => __($tlpobj->shortdesc))->pack(-anchor => 'w');
+ } else {
+ $f1docLb->Checkbutton(-variable => \$lvars{$coll}, -text => __($tlpobj->shortdesc))->pack(-anchor => 'w');
+ }
+ $i++;
+ }
+ my $f1docB = $f1doc->Frame;
+ $f1docB->pack(-expand => 1, -side => "bottom");
+ $f1docB->Button(-text => __("Select All"),
+ -command => sub { select_collections(\%lvars, @collections_lang_doc) })->pack(-side => 'left', -padx => "2m", -pady => "2m");
+ $f1docB->Button(-text => __("Deselect All"),
+ -command => sub { deselect_collections(\%lvars, @collections_lang_doc) })->pack(-side => 'left', -padx => "2m", -pady => "2m");
+ my $f2 = $sw->Frame; $f2->pack(-expand => 'x');
+ my $okbutton = $f2->Button(-text => __("Ok"),
+ -command => sub {
+ # we call the update only if something has changed
+ my $changed = 0;
+ for my $k (keys %lvars) {
+ if ($vars{$k} ne $lvars{$k}) {
+ $changed = 1;
+ last;
+ }
+ }
+ if ($changed) {
+ %vars = %lvars;
+ callback_select_collection();
+ }
+ $sw->destroy;
+ })->pack(-side => 'left', -padx => "2m", -pady => "2m");
+ my $cancelbutton = $f2->Button(-text => __("Cancel"),
+ -command => sub { $sw->destroy })->pack(-side => 'right', -padx => "2m", -pady => "2m");
+ $sw->bind('<Return>' => [ $okbutton, 'Invoke']);
+ $sw->bind('<Escape>' => [ $cancelbutton, 'Invoke']);
+}
+
+sub menu_select_symlink {
+ our ($lbin,$lman,$linfo);
+ our $osym = $vars{'option_path'};
+ our ($binlab,$binb,$manlab,$manb,$infolab,$infob);
+ sub set_unset_buttons {
+ $lbin = ($osym ? $vars{'option_sys_bin'} : '');
+ $linfo = ($osym ? $vars{'option_sys_info'} : '');
+ $lman = ($osym ? $vars{'option_sys_man'} : '');
+ if ($osym) {
+ $binb->configure (-state => 'normal');
+ $manb->configure (-state => 'normal');
+ $infob->configure(-state => 'normal');
+ } else {
+ $infob->configure(-state => 'disabled');
+ $manb->configure (-state => 'disabled');
+ $binb->configure (-state => 'disabled');
+ }
+ }
+ sub return_callback {
+ if ($osym) {
+ my $home = getenv('HOME');
+ $home = getenv('USERPROFILE') if (win32());
+ $home ||= '~';
+ $lbin =~ s/^~/$home/;
+ $linfo =~ s/^~/$home/;
+ $lman =~ s/^~/$home/;
+ $vars{'option_sys_bin'} = $lbin;
+ $vars{'option_sys_info'} = $linfo;
+ $vars{'option_sys_man'} = $lman;
+ }
+ $vars{'option_path'} = $osym;
+ toggle_and_set_opt_variable(\$vars{'option_path'}, \$pathadjyesno);
+ }
+ my $sw = $mainwindow->Toplevel(-title => __('Create symlinks in system directories'));
+ $sw->transient($mainwindow);
+ $sw->grab();
+ $sw->Checkbutton(-variable => \$osym,
+ -text => __("create symlinks in standard directories"),
+ -command => sub { set_unset_buttons(); } )->grid(-column => 1,
+ -row => 1,
+ -columnspan => 2,
+ -padx => "2m");
+ $binlab = $sw->Label(-text => __("binaries to"));
+ $binb = $sw->Entry(-textvariable => \$lbin);
+ $manlab = $sw->Label(-text => __("manpages to"));
+ $manb = $sw->Entry(-textvariable => \$lman);
+ $infolab = $sw->Label(-text => __("info to"));
+ $infob = $sw->Entry(-textvariable => \$linfo);
+ $binlab->grid(-row => 2, -column => 1, -sticky => "w", -padx => "2m");
+ $binb->grid(-row => 2, -column => 2, -sticky => "ew", -padx => "2m");
+ $manlab->grid(-row => 3, -column => 1, -sticky => "w", -padx => "2m");
+ $manb->grid(-row => 3, -column => 2, -sticky => "ew", -padx => "2m");
+ $infolab->grid(-row => 4, -column => 1, -sticky => "w", -padx => "2m");
+ $infob->grid(-row => 4, -column => 2, -sticky => "ew", -padx => "2m");
+ set_unset_buttons();
+ my $f2 = $sw->Frame; $f2->grid(-column => 1, -columnspan => 2, -row => 5);
+ my $okbutton = $f2->Button(-text => __("Ok"),
+ -command => sub { return_callback(); $sw->destroy })->pack(-side => 'left');
+ my $cancelbutton = $f2->Button(-text => __("Cancel"),
+ -command => sub { $sw->destroy })->pack(-side => 'right');
+ $sw->bind('<Return>' => [ $okbutton, 'Invoke']);
+ $sw->bind('<Escape>' => [ $cancelbutton, 'Invoke']);
+}
+
+sub menu_select_binsystems {
+ my $f2r;
+ my $f2;
+ my $sw = $mainwindow->Toplevel(-title => __('Binary system(s)'));
+ $sw->transient($mainwindow);
+ $sw->grab();
+ my @diskarchs = ();
+ foreach my $key (keys %vars) {
+ if ($key=~/binary_(.*)/) {
+ push @diskarchs, $1;
+ }
+ }
+ $sw->Label(-text => __("Select arch-os"))->pack(-padx => "2m", -pady => "2m");
+ $f2 = $sw->Frame;
+ my $f2l = $f2->Frame;
+ foreach my $sys (sort @diskarchs) {
+ $f2l->Checkbutton(-variable => \$vars{"binary_$sys"}, -text => platform_desc($sys))->pack(-anchor => 'w');
+ }
+ $f2l->pack(-side => 'left');
+ $f2->pack(-padx => "2m", -pady => "2m");
+ my $f3 = $sw->Frame;
+ my $okbutton = $f3->Button(-text => __("Ok"),
+ -command => sub { callback_select_systems() ; $sw->destroy })->pack(-side => 'left', -padx => "2m", -pady => "2m");
+ my $cancelbutton = $f3->Button(-text => __("Cancel"),
+ -command => sub { $sw->destroy })->pack(-side => 'right', -padx => "2m", -pady => "2m");
+ $f3->pack(-expand => 'x');
+ $sw->bind('<Return>' => [ $okbutton, 'Invoke']);
+ $sw->bind('<Escape>' => [ $cancelbutton, 'Invoke']);
+}
+
+
+sub menu_set_text {
+ my $w = shift;
+ my $t = shift;
+ # if in_place or portable not a complete interface
+ $w->configure(-text => $t, @_) if $w;
+}
+
+sub menu_set_schemebutton_text {
+ menu_set_text($schemebutton, "$vars{'selected_scheme'}");
+}
+
+sub menu_set_binbutton_text {
+ if (!win32()) {
+ menu_set_text($bintextbutton, __("%s out of %s", $vars{'n_systems_selected'}, $vars{'n_systems_available'}));
+ }
+}
+
+sub menu_set_collections_text {
+ menu_set_text($collectionstext, __("%s collections out of %s",
+ $vars{'n_collections_selected'}, $vars{'n_collections_available'})
+ . " (" . __("disk space required:") . " $vars{'total_size'} MB)");
+}
+
+sub menu_set_pathes_text {
+ if (check_on_lang_collection_installed()) {
+ # good
+ menu_set_text($langcoltext, "");
+ } else {
+ # bad
+ menu_set_text($langcoltext, __("(no language collection selected!)"), -foreground => "red");
+ }
+ if (TeXLive::TLUtils::texdir_check($vars{'TEXDIR'})) {
+ menu_set_text($texdirtext, native_slashify($vars{'TEXDIR'}), -foreground => "black");
+ } else {
+ menu_set_text($texdirtext, __("(default not writable - please change!)"), -foreground => "red");
+ }
+ menu_set_text($texmflocaltext, native_slashify($vars{'TEXMFLOCAL'}));
+ if ((-w $vars{'TEXMFSYSVAR'}) || (-w dirname($vars{'TEXMFSYSVAR'}))) {
+ menu_set_text($texmfsysvartext, native_slashify($vars{'TEXMFSYSVAR'}), -foreground => "black");
+ } elsif ("$vars{'TEXMFSYSVAR'}" =~ m;^$vars{'TEXDIR'};) {
+ if (TeXLive::TLUtils::texdir_check($vars{'TEXDIR'})) {
+ menu_set_text($texmfsysvartext, native_slashify($vars{'TEXMFSYSVAR'}), -foreground => "black");
+ } else {
+ menu_set_text($texmfsysvartext, __("(please change TEXDIR first!)"), -foreground => "red");
+ }
+ } else {
+ menu_set_text($texmfsysvartext, __("(default not writable - please change!)"));
+ }
+ if ((-w $vars{'TEXMFSYSCONFIG'}) || (-w dirname($vars{'TEXMFSYSCONFIG'}))) {
+ menu_set_text($texmfsysconfigtext, native_slashify($vars{'TEXMFSYSCONFIG'}), -foreground => "black");
+ } elsif ("$vars{'TEXMFSYSCONFIG'}" =~ m;^$vars{'TEXDIR'};) {
+ if (TeXLive::TLUtils::texdir_check($vars{'TEXDIR'})) {
+ menu_set_text($texmfsysconfigtext, native_slashify($vars{'TEXMFSYSCONFIG'}), -foreground => "black");
+ } else {
+ menu_set_text($texmfsysconfigtext, __("(please change TEXDIR first!)"), -foreground => "red");
+ }
+ } else {
+ menu_set_text($texmfsysconfigtext, __("(default not writable - please change!)"));
+ }
+ menu_set_text($texmfhometext, native_slashify($vars{'TEXMFHOME'}));
+}
+
+
+sub menu_update_texts {
+ menu_set_pathes_text;
+ menu_set_collections_text;
+ menu_set_binbutton_text;
+ menu_set_schemebutton_text;
+ $optletterstate = $::letterdesc[$vars{'option_letter'}];
+ $optfmtstate = ($vars{'option_fmt'} ? __("Yes") : __("No"));
+ $optsrcstate = ($vars{'option_src'} ? __("Yes") : __("No"));
+ $optdocstate = ($vars{'option_doc'} ? __("Yes") : __("No"));
+}
+
+sub callback_select_scheme {
+ my $s = shift;
+ select_scheme($s);
+ $editoryesno = ($vars{'collection-texworks'} ? __("Yes") : __("No"));
+ menu_update_texts();
+}
+
+sub callback_select_collection {
+ # special case for collection-texworks:
+ $editoryesno = ($vars{'collection-texworks'} ? __("Yes") : __("No"));
+ calc_depends();
+ select_scheme("scheme-custom");
+ update_numbers();
+ menu_update_texts();
+}
+
+sub callback_select_systems() {
+ if ($vars{"binary_win32"}) {
+ $vars{"collection-wintools"} = 1;
+ } else {
+ $vars{"collection-wintools"} = 0;
+ }
+ calc_depends();
+ update_numbers();
+ menu_update_texts();
+}
+
+sub callback_edit_directories {
+ my ($key,$val) = @_;
+ my $home = getenv('HOME');
+ if (win32()) {
+ $home = getenv('USERPROFILE');
+ $home =~ s!\\!/!g;
+ }
+ $home ||= '~';
+ $val =~ s!\\!/!g;
+ $vars{$key} = $val;
+ $vars{'TEXDIR'} =~ s/^~/$home/;
+ $vars{'TEXMFLOCAL'} =~ s/^~/$home/;
+ $vars{'TEXMFSYSVAR'} =~ s/^~/$home/;
+ $vars{'TEXMFSYSCONFIG'} =~ s/^~/$home/;
+ # only if we set TEXDIR we set the others in parallel
+ if ($key eq "TEXDIR") {
+ if ($vars{'TEXDIR'}=~/^(.*)\/$texlive_release$/) {
+ $vars{'TEXMFLOCAL'}="$1/texmf-local";
+ $vars{'TEXMFSYSVAR'}="$1/$texlive_release/texmf-var";
+ $vars{'TEXMFSYSCONFIG'}="$1/$texlive_release/texmf-config";
+ } elsif ($vars{'TEXDIR'}=~/^(.*)$/) {
+ $vars{'TEXMFLOCAL'}="$1/texmf-local";
+ $vars{'TEXMFSYSVAR'}="$1/texmf-var";
+ $vars{'TEXMFSYSCONFIG'}="$1/texmf-config";
+ }
+ $vars{'TEXDIRW'}=$vars{'TEXDIR'}
+ }
+ menu_update_texts();
+}
+
+sub callback_edit_var() {
+ my ($key,$val) = @_;
+ $vars{$key} = $val;
+ menu_update_texts();
+}
+
+sub dump_vars_stdout {
+ foreach my $k (keys %vars) {
+ print "DEBUG: vars{$k} = $vars{$k}\n";
+ }
+}
+
+sub toggle_portable {
+ my $td = $vars{'TEXDIR'};
+ my $b;
+ if ($vars{'portable'}) {
+ $vars{'portable'} = 0;
+ $portableyesno = __('No');
+ # enable some buttons
+ for $b ($tmflocalbutton, $tmfsysvarbutton, $tmfsysconfigbutton, $tmfhomebutton) {
+ $b->configure(-state => 'normal');
+ }
+ for $b ($pathbutton, $deskintbutton, $assocbutton, $adminbutton) {
+ $b->configure(-state => 'normal') if $b;
+ }
+ } else {
+ $vars{'portable'} = 1;
+ $portableyesno = __('Yes');
+ # disable some buttons. These should get a name first.
+ for $b ($tmflocalbutton, $tmfsysvarbutton, $tmfsysconfigbutton, $tmfhomebutton) {
+ $b->configure(-state => 'disabled');
+ }
+ $vars{'option_path'} = 0;
+ $vars{'option_desktop_integration'} = 0;
+ $vars{'option_file_assocs'} = 0;
+ $vars{'option_w32_multi_user'} = 0;
+ $deskintyesno = __("No");
+ $pathadjyesno = __("No");
+ $fileassocyesno = __("None");
+ $adminallyesno = __("No");
+ for $b ($pathbutton, $deskintbutton, $assocbutton, $adminbutton) {
+ $b->configure(-state => 'disabled') if $b;
+ }
+ }
+ set_texlive_default_dirs(); # this sub tests for portable and in_place
+ menu_set_pathes_text();
+ # same for some options
+}
+
+sub toggle_and_set_opt_variable {
+ my ($varsref, $toggleref, $choicesref) = @_;
+ my ($no, $yes) = $choicesref ? @$choicesref : (__('No'), __('Yes'));
+ $$toggleref = ($$toggleref eq $yes) ? $no : $yes;
+ $$varsref = 0;
+ $$varsref = 1 if ($$toggleref eq $yes);
+ calc_depends();
+ menu_update_texts();
+}
+
+1;
+
+__END__
+
+### Local Variables:
+### perl-indent-level: 2
+### tab-width: 2
+### indent-tabs-mode: nil
+### End:
+# vim:set tabstop=2 expandtab: #
diff --git a/Master/tlpkg/installer/install-menu-text-new.pl b/Master/tlpkg/installer/install-menu-text-new.pl
new file mode 100755
index 00000000000..092226643ab
--- /dev/null
+++ b/Master/tlpkg/installer/install-menu-text-new.pl
@@ -0,0 +1,1070 @@
+#!/usr/bin/env perl
+# $Id: install-menu-text.pl 20268 2010-10-31 07:26:14Z preining $
+# install-menu-txt.pl
+#
+# Copyright 2007, 2008, 2009, 2010 Norbert Preining, Karl Berry
+# Copyright 2007, 2008 Reinhard Kotucha
+# This file is licensed under the GNU General Public License version 2
+# or any later version.
+#
+# This file implements the text based menu system for the TeX Live installer.
+
+use vars qw(@::end_install_hook $::opt_no_cls);
+
+our %vars;
+our $tlpdb;
+our @media_available;
+our $previoustlpdb;
+our @collections_std;
+our @collections_lang;
+our @collections_lang_doc;
+our $texlive_release;
+
+my $MENU_CONTINUE = -1;
+our $MENU_INSTALL = 0;
+our $MENU_ABORT = 1;
+our $MENU_QUIT = 2;
+
+
+my $RETURN = $MENU_CONTINUE;
+
+# issue welcome message on end of installation
+push @::end_install_hook,
+ sub { if (win32()) { print TeXLive::TLUtils::welcome(); }
+ else { print TeXLive::TLUtils::welcome_paths(); } };
+
+sub clear_screen {
+ return 0 if ($::opt_no_cls);
+ system (unix() ? 'clear' : 'cls');
+}
+
+sub string_to_list {
+ my $string=shift;
+ return split(//, $string);
+}
+
+sub button {
+ my $val=shift;
+ return ($val)? '[X]':'[ ]';
+}
+
+sub hbar {
+ return '=' x79, "\n";
+}
+
+sub toggle {
+ my $var=shift;
+ $vars{$var} = ($vars{$var} ? 0 : 1);
+}
+
+sub menu_head {
+ my $text = shift;
+ clear_screen;
+ print hbar(), "$text\n\n";
+}
+
+sub other_options {
+ my @options=@_;
+ my %opts=(
+ '-' => 'deselect all',
+ '+' => 'select all',
+ 'H' => 'help',
+ 'R' => 'return to main menu',
+ 'Q' => 'quit'
+ );
+
+ $opts{'I'}=$vars{'portable'} ? 'start portable installation' : 'start hd installation';
+
+ print "\nActions:";
+ if ($options[$#options] eq 'diskspace') {
+ pop @options;
+ calc_depends ();
+ print " (disk space required: $vars{'total_size'} MB)";
+ }
+ print "\n";
+
+ for my $option (@options) {
+ if (defined $opts{"$option"}) {
+ printf " <%s> %s\n", $option, $opts{$option};
+ } else {
+ die "other_options: $opts{$option} undefined.\n";
+ }
+ }
+}
+
+sub prompt {
+ my $prompt = shift;
+ print "\n$prompt: ";
+ my $answer = <STDIN>;
+ $answer = "q" if !defined($answer);
+ chomp($answer);
+ return "$answer";
+}
+
+# The menu loop. A menu is a function. Its return value is a
+# reference to another menu or to itself.
+sub run_menu_text {
+ my (@args) = @_;
+ # the text mode installer does not take interest in any argument
+ # but the -old-installation-found
+ while (@args) {
+ my $f = shift @args;
+ if ($f =~ m/^-old-installation-found=(.*)$/) {
+ my $dn = $1;
+ print "\nAn old installation of TeX Live has been found in $dn\n";
+ print "
+If you want the selection of collections and various options being taken
+over press `y', otherwise anything else.
+
+Import settings from previous TeX Live installation: (y/n): ";
+ chomp(my $yn = <STDIN>);
+ if ($yn =~ m/^y$/i) {
+ import_settings_from_old_tlpdb($dn);
+ }
+ }
+ }
+ my $menu=\&main_menu;
+ while ($RETURN == $MENU_CONTINUE) {
+ $menu=$menu->();
+ }
+ return($RETURN);
+}
+$::run_menu = \&run_menu_text;
+
+sub binary_menu {
+ my %command=(
+ 'self' => \&binary_menu,
+ 'R' => \&main_menu,
+ 'Q' => \&quit
+ );
+
+ my @binaries;
+ my @keys=string_to_list "abcdefghijklmopstuvwxyz";
+ my $index=0;
+ my %keyval;
+ my $selected_platform;
+
+ menu_head "Available platforms:";
+
+ foreach my $key (keys %vars) {
+ if ($key =~ /binary_(.*)/) {
+ push @binaries, $1;
+ }
+ }
+ @binaries=sort(@binaries);
+
+ foreach my $binary (@binaries) {
+ printf " %s %s %-16s %s\n", $keys[$index],
+ button($vars{"binary_$binary"}),
+ "$binary",
+ platform_desc($binary);
+ $keyval{"$keys[$index]"} = "binary_$binary";
+ ++$index;
+ }
+ other_options qw(- + R Q diskspace);
+
+ my $answer = prompt 'Enter letter(s) to select platforms';
+
+ my @keystrokes=string_to_list $answer;
+
+ foreach my $keystroke (@keystrokes) {
+ if ($keystroke eq '-') {
+ for my $binary (@binaries) {
+ $vars{"binary_$binary"}=0 if defined $vars{"binary_$binary"};
+ }
+ }
+ if ($keystroke eq '+') {
+ for my $binary (@binaries) {
+ $vars{"binary_$binary"}=1 if defined $vars{"binary_$binary"};
+ }
+ }
+ if (defined $keyval{$keystroke}) {
+ toggle "$keyval{$keystroke}";
+ } elsif (!defined $command{"\u$answer"}) {
+ print "Unknown command: $keystroke\n\n";
+ }
+ }
+ if ($vars{"binary_win32"}) {
+ $vars{"collection-wintools"} = 1;
+ } else {
+ $vars{"collection-wintools"} = 0;
+ }
+ if (defined $command{"\u$answer"}) {
+ return $command{"\u$answer"}->();
+ } else {
+ return $command{'self'}->();
+ }
+}
+
+
+sub scheme_menu {
+ my %command=(
+ 'self' => \&scheme_menu,
+ 'R' => \&main_menu,
+ 'Q' => \&quit
+ );
+
+ my @schemes;
+ my @keys=string_to_list "abcdefghijklmnopstuvwxyz";
+ my %keyval;
+ my $index=0;
+
+ menu_head 'Select scheme:';
+
+ foreach my $pkg ($tlpdb->schemes) {
+ push @schemes, $pkg;
+ $vars{"$pkg"}=($vars{'selected_scheme'} eq $pkg)? 1:0;
+ }
+ @schemes=sort @schemes;
+ push @schemes, "scheme-custom";
+
+ foreach my $scheme (@schemes) {
+ $keyval{$keys[$index]}="$scheme";
+ if ($scheme ne "scheme-custom") {
+ my $tlpobj = $tlpdb->get_package("$scheme");
+ printf " %s %s %s\n", $keys[$index], button($vars{"$scheme"}),
+ $tlpobj->shortdesc;
+ } else {
+ printf " %s %s custom selection of collections\n",
+ $keys[$index], button($vars{'selected_scheme'} eq "scheme-custom");
+ }
+ ++$index;
+ }
+
+ select_scheme($vars{'selected_scheme'});
+
+ if ($vars{"binary_win32"}) {
+ $vars{"collection-wintools"} = 1;
+ } else {
+ $vars{"collection-wintools"} = 0;
+ }
+
+ other_options qw(R Q diskspace);
+ my $answer = prompt 'Enter letter to select scheme';
+
+ if (defined $keyval{"$answer"}) {
+ $vars{'selected_scheme'}=$keyval{"$answer"};
+ select_scheme($vars{'selected_scheme'});
+ return $command{'self'}->();
+ }
+ if (defined $command{"\u$answer"}) {
+ return $command{"\u$answer"}->();
+ } else {
+ print "Unknown command: $answer\n\n";
+ return $command{'self'}->();
+ }
+}
+
+
+sub collection_menu {
+ my %command=(
+ 'self' => \&collection_menu,
+ 'R' => \&main_menu,
+ 'Q' => \&quit
+ );
+
+ my @collections;
+ my @keys=string_to_list "abcdefghijklmnopstuvwxyzABCDEFGHIJKLMNOPSTUVWXYZ";
+ my %keyval;
+ my $index=0;
+ my @coll_short_desc;
+ my @coll_long_desc;
+
+ menu_head 'Select collections:';
+
+ @collections=sort @collections_std;
+
+ foreach my $collection (@collections) {
+ next if ($collection eq 'collection-perl');
+ my $tlpobj = $tlpdb->get_package("$collection");
+ if (length $tlpobj->shortdesc>30) {
+ push @coll_long_desc, $collection;
+ } else {
+ push @coll_short_desc, $collection;
+ }
+ }
+ my $singlecolumn_index=@coll_short_desc-1;
+
+##<cols=2>
+ my $lines=@coll_short_desc/2;
+ ++$lines if (@coll_short_desc%2);
+ for (0..$lines-1) {
+ $index=$_;
+ my $collection=$coll_short_desc[$index];
+ my $tlpobj = $tlpdb->get_package("$collection");
+ $keyval{$keys[$index]}="$collection";
+ printf " %s %s %-33s", $keys[$index], button($vars{"$collection"}),
+ substr($tlpobj->shortdesc,0,33);
+ if (defined $coll_short_desc[$index+$lines]) {
+ my $collection=$coll_short_desc[$index+$lines];
+ my $tlpobj=$tlpdb->get_package("$collection");
+ $keyval{$keys[$index+$lines]}="$collection";
+ printf " %s %s %-32s\n", $keys[$index+$lines],
+ button($vars{"$collection"}), substr($tlpobj->shortdesc,0,32);
+ } else {
+ print "\n";
+ }
+ }
+##</cols=2>
+ $index=$singlecolumn_index;
+# print "\n$index\n\n";
+ foreach my $collection (@coll_long_desc) {
+ my $tlpobj=$tlpdb->get_package("$collection");
+ $keyval{$keys[$index+1]}="$collection";
+ printf " %s %s %s\n", $keys[$index+1], button($vars{"$collection"}),
+ $tlpobj->shortdesc;
+ ++$index;
+ }
+##</cols=1>
+
+ other_options qw(- + R Q diskspace);
+ my $answer = prompt 'Enter letter(s) to select collection(s)';
+
+ my @keystrokes=string_to_list $answer;
+
+ foreach my $keystroke (@keystrokes) {
+ if ($keystroke eq '-') {
+ for my $collection (@collections) {
+ $vars{"$collection"}=0 if defined $vars{"$collection"};
+ }
+ }
+ if ($keystroke eq '+') {
+ for my $collection (@collections) {
+ $vars{"$collection"}=1 if defined $vars{"$collection"};
+ }
+ }
+ if (defined $keyval{$keystroke}) {
+ toggle "$keyval{$keystroke}";
+ } elsif (!defined $command{"\u$answer"}) {
+ print "Unknown command: $keystroke\n\n";
+ }
+ }
+
+ if (defined $command{"\u$answer"}) {
+ # if we play around with collections we also select custom-scheme
+ # but we do not switch back to originally afterwards, too complicated
+ # to be done
+ select_scheme("scheme-custom");
+ return $command{"\u$answer"}->();
+ } else {
+ return $command{'self'}->();
+ }
+}
+
+sub language_menu {
+ my %command=(
+ 'self' => \&language_menu,
+ 'R' => \&main_menu,
+ 'Q' => \&quit
+ );
+
+ my @languages;
+ my @lang_docs;
+ my @lang_keys=string_to_list "abcdefghijklmnopstuvwxyz0123456789";
+ my @lang_doc_keys=string_to_list "ABCDEFGHIJKLMNOPSTUVWXYZ";
+ my %keyval;
+ my $lang_index=0;
+ my $lang_doc_index=0;
+ my $lines;
+
+ menu_head 'Language support:';
+
+ @languages=sort @collections_lang;
+ @lang_docs=sort @collections_lang_doc;
+
+ $lines=@languages/2;
+ ++$lines if (@languages%2);
+ for my $index (0..$lines-1) {
+ my $language=$languages[$index];
+ my $tlpobj = $tlpdb->get_package("$language");
+ $keyval{$lang_keys[$index]}="$language";
+ printf " %s %s %-33s", $lang_keys[$index], button($vars{"$language"}),
+ substr($tlpobj->shortdesc,0,33);
+ if (defined $languages[$index+$lines]) {
+ my $language=$languages[$index+$lines];
+ my $tlpobj = $tlpdb->get_package("$language");
+ $keyval{$lang_keys[$index+$lines]}="$language";
+ printf " %s %s %-32s\n", $lang_keys[$index+$lines],
+ button($vars{"$language"}), substr($tlpobj->shortdesc,0,32);
+ } else {
+ print "\n";
+ }
+ }
+
+ print "\nLanguage-specific documentation:\n\n";
+
+ $lines=@lang_docs/2;
+ ++$lines if (@lang_docs%2);
+ for my $index (0..$lines-1) {
+ my $lang_doc=$lang_docs[$index];
+ my $tlpobj = $tlpdb->get_package("$lang_doc");
+ $keyval{$lang_doc_keys[$index]}="$lang_doc";
+ printf " %s %s %-33s", $lang_doc_keys[$index], button($vars{"$lang_doc"}),
+ substr($tlpobj->shortdesc,0,33);
+ if (defined $lang_docs[$index+$lines]) {
+ my $lang_doc=$lang_docs[$index+$lines];
+ my $tlpobj = $tlpdb->get_package("$lang_doc");
+ $keyval{$lang_doc_keys[$index+$lines]}="$lang_doc";
+ printf " %s %s %-32s\n", $lang_doc_keys[$index+$lines],
+ button($vars{"$lang_doc"}), substr($tlpobj->shortdesc,0,32);
+ } else {
+ print "\n";
+ }
+ }
+
+ other_options qw (+ - R Q diskspace);
+ my $answer = prompt 'Enter letter(s) to select language(s)';
+
+ my @keystrokes=string_to_list $answer;
+
+ foreach my $keystroke (@keystrokes) {
+ if ($keystroke eq '-') {
+ for my $collection (@languages,@lang_docs) {
+ $vars{"$collection"}=0 if defined $vars{"$collection"};
+ }
+ }
+ if ($keystroke eq '+') {
+ for my $collection (@languages,@lang_docs) {
+ $vars{"$collection"}=1 if defined $vars{"$collection"};
+ }
+ }
+ if (defined $keyval{$keystroke}) {
+ toggle "$keyval{$keystroke}";
+ } elsif (!defined $command{"\u$answer"}) {
+ print "Unknown command: $keystroke\n\n";
+ }
+ }
+
+ if (defined $keyval{"$answer"}) {
+ return $command{'self'}->();
+ }
+ if (defined $command{"\u$answer"}) {
+ select_scheme("scheme-custom");
+ return $command{"\u$answer"}->();
+ } else {
+ return $command{'self'}->();
+ }
+}
+
+
+sub directories_menu
+{
+ my %command=(
+ 'self' => \&directories_menu,
+ 'R' => \&main_menu,
+ 'Q' => \&quit
+ );
+
+ my $maindir = 'TEXDIR';
+
+ menu_head "Directories setup:";
+ if (!TeXLive::TLUtils::texdir_check($vars{$maindir})) {
+ print "!! The default location as given below can't be written to.
+!! Either change the destination directory using <1> or create it
+!! outside this script.
+";
+ }
+ if (!$vars{'in_place'}) {
+ print <<"EOF";
+ <1> TEXDIR: $vars{'TEXDIR'}
+ support tree: $vars{'TEXDIR'}/texmf
+EOF
+ } else {
+ print <<"EOF";
+ TEXDIR: $vars{'TEXDIR'}
+ support tree: $vars{'TEXDIR'}/texmf
+EOF
+ }
+ if (!$vars{'portable'}) {
+ print <<"EOF";
+
+ <2> TEXMFLOCAL: $vars{'TEXMFLOCAL'}
+ <3> TEXMFSYSVAR: $vars{'TEXMFSYSVAR'}
+ <4> TEXMFSYSCONFIG: $vars{'TEXMFSYSCONFIG'}
+
+ <5> TEXMFVAR: $vars{'TEXMFVAR'}
+ <6> TEXMFCONFIG: $vars{'TEXMFCONFIG'}
+ <7> TEXMFHOME: $vars{'TEXMFHOME'}
+
+EOF
+
+ if (win32) {
+ print " Note: ~ will expand to %USERPROFILE%\n";
+ } else {
+ print " Note: ~ will expand to \$HOME (or to %USERPROFILE% on Windows)\n";
+ }
+ }
+
+ other_options qw(R Q);
+ my $answer = prompt 'Enter command';
+
+ if ("\u$answer" eq '1' and !$vars{'in_place'}) {
+ print "New value for $maindir [$vars{$maindir}]: ";
+ $answer = &input_dirname ();
+ $vars{$maindir} = $answer if $answer ne "";
+ if ($vars{$maindir}=~/^(.*)\/$texlive_release$/) {
+ $vars{'TEXMFLOCAL'}="$1/texmf-local";
+ $vars{'TEXMFSYSVAR'}="$1/$texlive_release/texmf-var";
+ $vars{'TEXMFSYSCONFIG'}="$1/$texlive_release/texmf-config";
+ } elsif ($vars{$maindir}=~/^(.*)$/) {
+ $vars{'TEXMFLOCAL'}="$1/texmf-local";
+ $vars{'TEXMFSYSVAR'}="$1/texmf-var";
+ $vars{'TEXMFSYSCONFIG'}="$1/texmf-config";
+ }
+ return $command{'self'};
+
+ } elsif ("\u$answer" eq '2' and !$vars{'portable'}) {
+ print "New value for TEXMFLOCAL [$vars{'TEXMFLOCAL'}]: ";
+ $answer = &input_dirname ();
+ $vars{'TEXMFLOCAL'} = $answer if $answer ne "";
+ return $command{'self'};
+
+ } elsif ("\u$answer" eq '3' and !$vars{'portable'}) {
+ print "New value for TEXMFSYSVAR [$vars{'TEXMFSYSVAR'}]: ";
+ $answer = &input_dirname ();
+ $vars{'TEXMFSYSVAR'} = $answer if $answer ne "";
+ return $command{'self'};
+
+ } elsif ("\u$answer" eq '4' and !$vars{'portable'}) {
+ print "New value for TEXMFSYSCONFIG [$vars{'TEXMFSYSCONFIG'}]: ";
+ $answer = &input_dirname ();
+ $vars{'TEXMFSYSCONFIG'} = $answer if $answer ne "";
+ return $command{'self'};
+
+ } elsif ("\u$answer" eq '5' and !$vars{'portable'}) {
+ print "New value for TEXMFVAR [$vars{'TEXMFVAR'}]: ";
+ $answer = &input_dirname ("noexpansion");
+ $vars{'TEXMFVAR'} = $answer if $answer ne "";
+ return $command{'self'};
+
+ } elsif ("\u$answer" eq '6' and !$vars{'portable'}) {
+ print "New value for TEXMFCONFIG [$vars{'TEXMFCONFIG'}]: ";
+ $answer = &input_dirname ("noexpansion");
+ $vars{'TEXMFCONFIG'} = $answer if $answer ne "";
+ return $command{'self'};
+
+ } elsif ("\u$answer" eq '7' and !$vars{'portable'}) {
+ print "New value for TEXMFHOME [$vars{'TEXMFHOME'}]: ";
+ $answer = &input_dirname ("noexpansion");
+ $vars{'TEXMFHOME'} = $answer if $answer ne "";
+ return $command{'self'};
+ }
+
+ if (defined $command{"\u$answer"}) {
+ return $command{"\u$answer"}->();
+ } else {
+ print "Unknown command: $answer\n\n";
+ return $command{'self'}->();
+ }
+}
+
+
+# Helper function to read a directory name and clean it up.
+# Unless NO_EXPANSION is true, convert to absolute path.
+#
+sub input_dirname
+{
+ my $noexpansion = shift;
+ chomp (my $answer = <STDIN>);
+ return "" if $answer eq "";
+
+ $answer =~ s!\\!/!g if win32(); # switch to forward slashes
+
+ if (!$noexpansion) {
+ my $home = getenv('HOME');
+ $home = getenv('USERPROFILE') if win32();
+ $home ||= '~';
+ $answer =~ s/^~/$home/; # $home expansion
+ }
+
+ if ($answer !~ m/^~/) {
+ # relative paths are unlikely to work in texmf.cnf, et al.,
+ # and don't have any apparent practical use. Convert to absolute.
+ if (! File::Spec->file_name_is_absolute($answer)) {
+ $answer = Cwd::abs_path($answer);
+ }
+ }
+ return $answer;
+}
+
+
+$vars{'page'}=0;
+
+sub html2text {
+ my $filename=shift;
+ my @text;
+ open IN, "$filename";
+ @all_lines=<IN>;
+ close IN;
+ chomp @all_lines;
+
+ my $itemcnt;
+ my $ordered_list=0;
+ my $h1_indent=25;
+ my $h2_indent=3;
+ my $h3_indent=6;
+
+ for (@all_lines) {
+ next if /DOCTYPE/;
+ next if /<!--/;
+ next if /<title/i;
+ next if /<\/?body/i;
+ next if /<\/?html/i;
+ next if /<\/?head/i;
+ next if /<\/?meta/i;
+ next if /^\s*$/; # ignore empty lines
+
+ s/<i>/"/gi; s/<\/i>/"/gi; # italics
+ s/<tt>/'/gi; s/<\/tt>/'/gi; # typewriter
+ s/<p>.*//gi; # paragraphs
+ s/<\/ul>.*//gi; # unsorted lists
+ s/<\/ol>.*//gi; # ordered lists
+ s/&mdash;/--/gi; # mdash
+ s/&lt;/</gi; s/&gt;/>/gi; # < and >
+ if (/<h1>(.*?)<\/h1>/i) {
+ push @text, " " x $h1_indent. "$1\n";
+ push @text, " " x $h1_indent. "=" x (length $1). "\n";
+ push @text, "\n";
+ } elsif (/<h2>(.*?)<\/h2>/i) {
+ push @text, "\n";
+ push @text, " " x $h2_indent. "$1\n";
+ push @text, " " x $h2_indent. "~" x (length $1). "\n";
+ push @text, "\n";
+ } elsif (/<h3>(.*?)<\/h3>/i) {
+ push @text, "\n";
+ push @text, " " x $h3_indent. "$1\n";
+ push @text, " " x $h3_indent. "-" x (length $1). "\n";
+ push @text, "\n";
+ } elsif (/<ol>/i) {
+ $ordered_list=1;
+ $itemcnt=1;
+ } elsif (/<ul>/i) {
+ $ordered_list=0;
+ } elsif (/^\s*<li>\s*(.*)/) {
+ if ($ordered_list) {
+ push @text, "\n";
+ push @text, " $itemcnt. $1\n";
+ ++$itemcnt;
+ } else {
+ push @text, "\n";
+ push @text, " * $1\n";
+ }
+ } else {
+ push @text, "$_\n";
+ }
+ }
+ return @text;
+}
+
+
+sub help_menu {
+ my %command=(
+ 'self' => \&help_menu,
+ 'R' => \&main_menu,
+ 'Q' => \&quit
+ );
+ my $installer_help="$installerdir/tlpkg/installer/install-tl.html";
+
+ clear_screen;
+
+ my @text=html2text "$installer_help";
+ my $lines=(@text);
+ my $overlap=3;
+ my $lps=32; # lines per screen - overlap
+ my $firstline=$vars{'page'}*$lps;
+ my $lastline=$firstline+$lps+$overlap;
+ my $line=0;
+# print "<<<$firstline>>> <<<$lastline>>>\n";
+ for (@text) {
+ print "$_" if ($line>=$firstline and $line<=$lastline);
+ ++$line;
+ }
+ print "\n", hbar,
+ " <T> top <N> next page <P> previous page <R> return"
+ . " <Q> quit --", $vars{'page'}+1, "--\n";
+
+ my $answer = prompt 'Enter command';
+
+ if ("\u$answer" eq 'T') {
+ $vars{'page'}=0;
+ return $command{'self'};
+
+ } elsif ("\u$answer" eq 'N') {
+ $vars{'page'}+=1 unless $lastline>$lines;
+ return $command{'self'};
+
+ } elsif ("\u$answer" eq 'P') {
+ $vars{'page'}-=1 if $vars{'page'}>=1;
+ return $command{'self'};
+
+ } elsif (defined $command{"\u$answer"}) {
+ return $command{"\u$answer"};
+
+ } else {
+ print "Unknown command: $answer\n\n";
+ return $command{'self'};
+ }
+}
+
+
+sub options_menu {
+ my $b_path=button($vars{'option_path'});
+ my $b_doc=button($vars{'option_doc'});
+ my $b_src=button($vars{'option_src'});
+ my $b_fmt=button($vars{'option_fmt'});
+ my $b_letter=button($vars{'option_letter'});
+ my $b_deskint=button($vars{'option_desktop_integration'});
+ my $b_admin=button($vars{'option_w32_multi_user'});
+ my $b_addoneditor=button($vars{'collection-texworks'});
+ my $b_restricted=button($vars{'option_write18_restricted'});
+
+ my $sys_bin=$vars{'option_sys_bin'};
+ my $sys_man=$vars{'option_sys_man'};
+ my $sys_info=$vars{'option_sys_info'};
+
+ my $t_sys_bin=($vars{'option_path'})? $vars{'option_sys_bin'}:'';
+ my $t_sys_man=($vars{'option_path'})? $vars{'option_sys_man'}:'';
+ my $t_sys_info=($vars{'option_path'})? $vars{'option_sys_info'}:'';
+
+ my %command=(
+ 'self' => \&options_menu,
+ 'R' => \&main_menu,
+ 'Q' => \&quit
+ );
+
+ clear_screen;
+ menu_head "Options setup:";
+
+ print <<"EOF";
+ <P> use letter size instead of A4 by default: $b_letter
+ <E> execution of restricted list of programs: $b_restricted
+ <F> create format files: $b_fmt
+EOF
+;
+ if ($vars{'doc_splitting_supported'} and !$vars{'in_place'}) {
+ print " <D> install font/macro doc tree: $b_doc\n";
+ }
+ if ($vars{'src_splitting_supported'} and !$vars{'in_place'}) {
+ print " <S> install font/macro source tree: $b_src\n";
+ }
+ if (!$vars{'portable'}) {
+ if (unix() || $::opt_all_options) {
+ print <<"EOF";
+ <L> create symlinks in standard directories: $b_path
+ binaries to: $t_sys_bin
+ manpages to: $t_sys_man
+ info to: $t_sys_info
+EOF
+;
+ } else {
+ print <<"EOF";
+ <L> adjust registry entry for path: $b_path
+EOF
+;
+ }
+ if (win32() || $::opt_all_options) {
+ print " <M> install menu items, shortcuts, etc: $b_deskint\n";
+ print " <N> update file associations: [$::fileassocdesc[$vars{'option_file_assocs'}]]\n";
+ if ($::opt_all_options || TeXLive::TLWinGoo::admin()) {
+ # if we are admin we allow normal user installation, too
+ print " <U> make installation available to all users: $b_admin\n";
+ }
+ }
+ }
+ if (win32() || $::opt_all_options) {
+ print " <W> install TeXworks front end: $b_addoneditor\n";
+ }
+ other_options qw(R Q diskspace);
+ my $answer = prompt 'Enter command';
+
+ # option_path
+
+ if (unix()) {
+ if (("\u$answer" eq 'L') and !$vars{'portable'}) {
+ my $home = getenv('HOME');
+ $home = getenv('USERPROFILE') if (win32());
+ $home ||= '~';
+ toggle 'option_path';
+ if ($vars{'option_path'}) {
+ print "New value for binary directory [$sys_bin]: ";
+ chomp($answer=<STDIN>);
+ $vars{'option_sys_bin'} = "$answer" if (length $answer);
+ $vars{'option_sys_bin'} =~ s@\\@/@g if (win32());
+ $vars{'option_sys_bin'} =~ s/^~/$home/;
+ if ($vars{'option_sys_bin'}=~/^(.*)\/bin$/) {
+ $vars{'option_sys_man'}="$1/man";
+ $vars{'option_sys_info'}="$1/info";
+ }
+ print "New value for man directory [$vars{'option_sys_man'}]: ";
+ chomp($answer=<STDIN>);
+ $vars{'option_sys_man'}="$answer" if (length $answer);
+ $vars{'option_sys_man'} =~ s@\\@/@g if (win32());
+ $vars{'option_sys_man'} =~ s/^~/$home/;
+
+ print "New value for info directory [$vars{'option_sys_info'}]: ";
+ chomp($answer=<STDIN>);
+ $vars{'option_sys_info'}="$answer" if (length $answer);
+ $vars{'option_sys_info'} =~ s@\\@/@g if (win32());
+ $vars{'option_sys_info'} =~ s/^~/$home/;
+ }
+ return $command{'self'};
+ }
+ } else {
+ if (("\u$answer" eq 'L') and !$vars{'portable'}) {
+ my $home = getenv('HOME');
+ $home = getenv('USERPROFILE') if (win32());
+ $home ||= '~';
+ toggle 'option_path';
+ return $command{'self'};
+ }
+ }
+
+ # option_desktop_integration, option_file_assocs
+
+ if (win32() || $::opt_all_options) {
+ if ("\u$answer" eq 'M' and !$vars{'portable'}) {
+ toggle 'option_desktop_integration';
+ return $command{'self'};
+
+ } elsif ("\u$answer" eq 'N' and !$vars{'portable'}) {
+ print "New value for file_assocs:\n";
+ print " 0 -- don't tweak the file associations\n";
+ print " 1 -- only add new file associations, don't overwrite old ones\n";
+ print " 2 -- always create file associations to TeX Live programs\n";
+ print "New value for file_assocs [$vars{'option_file_assocs'}]: ";
+ chomp (my $a = <STDIN>);
+ if ($a eq "0" || $a eq "1" || $a eq "2") {
+ $vars{'option_file_assocs'} = $a;
+ }
+ return $command{'self'};
+
+ } elsif ("\u$answer" eq 'U' and !$vars{'portable'}) {
+ toggle 'option_w32_multi_user';
+ return $command{'self'};
+ }
+ }
+
+ # other options
+
+ if ("\u$answer" eq 'P') {
+ toggle 'option_letter';
+ return $command{'self'};
+
+ } elsif ("\u$answer" eq 'F') {
+ toggle 'option_fmt';
+ return $command{'self'};
+
+ } elsif ("\u$answer" eq 'E') {
+ toggle 'option_write18_restricted';
+ return $command{'self'};
+
+ } elsif ("\u$answer" eq 'S' and !$vars{'in_place'}) {
+ toggle 'option_src';
+ return $command{'self'};
+
+ } elsif ("\u$answer" eq 'D' and !$vars{'in_place'}) {
+ toggle 'option_doc';
+ return $command{'self'};
+
+ } elsif (defined $command{"\u$answer"}) {
+ return $command{"\u$answer"};
+
+ } elsif (("\u$answer" eq 'W') && ($::opt_all_options || win32()) &&
+ !$vars{'in_place'} ) {
+ toggle 'collection-texworks';
+ return $command{'self'};
+
+ } else {
+ print "Unknown or unsupported command: $answer\n\n";
+ return $command{'self'};
+ }
+}
+
+
+sub quit {
+ exit 0;
+ $RETURN = $MENU_QUIT;
+}
+
+sub do_install {
+ $RETURN = $MENU_INSTALL;
+}
+
+sub toggle_portable {
+ if ($vars{'portable'}) {
+ $vars{'portable'} = 0;
+ $vars{'option_desktop_integration'} = 0;
+ $vars{'option_path'} = 0;
+ $vars{'option_file_assocs'} = 0;
+ $vars{'option_w32_multi_user'} = 0;
+ } else {
+ $vars{'portable'} = 1;
+ $vars{'option_desktop_integration'} = 1;
+ $vars{'option_path'} = 1;
+ $vars{'option_file_assocs'} = 1;
+ $vars{'option_w32_multi_user'} = 1;
+ }
+ set_texlive_default_dirs(); # this sub tests for portable and in_place
+ main_menu;
+}
+
+sub main_menu {
+ my $this_platform=platform_desc($vars{'this_platform'});
+
+ my $b_path=button($vars{'option_path'});
+ my $b_doc=button($vars{'option_doc'});
+ my $b_src=button($vars{'option_src'});
+ my $b_fmt=button($vars{'option_fmt'});
+ my $b_letter=button($vars{'option_letter'});
+ my $b_deskint=button($vars{'option_desktop_integration'});
+ my $b_admin=button($vars{'option_w32_multi_user'});
+ my $b_addoneditor=button($vars{'collection-texworks'});
+ my $b_restricted=button($vars{'option_write18_restricted'});
+
+ my $warn_nobin;
+
+ $warn_nobin=set_install_platform;
+
+ my $maindir = 'TEXDIR';
+
+ $vars{'n_systems_selected'}=0;
+ $vars{'n_collections_selected'}=0;
+ foreach my $key (keys %vars) {
+ if ($key=~/^binary.*/) {
+ ++$vars{'n_systems_selected'} if $vars{$key}==1;
+ }
+ if ($key=~/^collection/) {
+ ++$vars{'n_collections_selected'} if $vars{$key}==1;
+ }
+ }
+ calc_depends();
+
+ my %command = (
+ 'self' => \&main_menu,
+ 'D' => \&directories_menu,
+ 'H' => \&help_menu,
+ 'I' => \&do_install,
+ 'O' => \&options_menu,
+ 'Q' => \&quit,
+ 'V' => \&toggle_portable,
+ );
+ if (!$vars{'in_place'}) {
+ $command{'B'} = \&binary_menu if unix();
+ $command{'C'} = \&collection_menu;
+ $command{'L'} = \&language_menu;
+ $command{'S'} = \&scheme_menu;
+ }
+
+ clear_screen;
+ print <<"EOF";
+======================> TeX Live installation procedure <=====================
+
+=======> Note: Letters/digits in <angle brackets> indicate menu items <=======
+=======> for commands or configurable options <=======
+
+ Detected platform: $this_platform
+ $warn_nobin
+EOF
+
+ if (!$vars{'in_place'}) {
+ print <<"EOF";
+ <B> platforms: $vars{'n_systems_selected'} out of $vars{'n_systems_available'}
+
+ <S> installation scheme ($vars{'selected_scheme'})
+ $vars{'n_collections_selected'} collections out of $vars{'n_collections_available'}, disk space required: $vars{'total_size'} MB
+
+ Customizing installation scheme:
+ <C> standard collections
+ <L> language collections
+EOF
+
+ if (!check_on_lang_collection_installed()) {
+ print " !! No language specific collection selected!\n";
+ print " !! If you only write American English documents that is fine!\n";
+ }
+ }
+ print <<"EOF";
+
+ <D> directories:
+ TEXDIR (the main TeX directory):
+EOF
+
+ if (TeXLive::TLUtils::texdir_check($vars{$maindir})) {
+ print " $vars{$maindir}\n";
+ } else {
+ print " !! default location: $vars{$maindir}\n";
+ print " !! is not writable, please select a different one!\n";
+ }
+ print <<"EOF";
+ TEXMFLOCAL (directory for site-wide local files):
+ $vars{'TEXMFLOCAL'}
+ TEXMFSYSVAR (directory for variable and automatically generated data):
+ $vars{'TEXMFSYSVAR'}
+ TEXMFSYSCONFIG (directory for local config):
+ $vars{'TEXMFSYSCONFIG'}
+ TEXMFVAR (personal directory for variable and automatically generated data):
+ $vars{'TEXMFVAR'}
+ TEXMFCONFIG (personal directory for local config):
+ $vars{'TEXMFCONFIG'}
+ TEXMFHOME (directory for user-specific files):
+ $vars{'TEXMFHOME'}
+
+EOF
+
+print <<"EOF";
+ <O> options:
+ $b_letter use letter size instead of A4 by default
+ $b_restricted allow execution of restricted list of programs via \\write18
+ $b_fmt create all format files
+EOF
+
+ if (!$vars{'in_place'}) {
+ if ($vars{'doc_splitting_supported'}) {
+ print " $b_doc install macro/font doc tree\n";
+ }
+ if ($vars{'src_splitting_supported'}) {
+ print " $b_src install macro/font source tree\n";
+ }
+ }
+ if (win32()) {
+ if (!$vars{'portable'}) {
+ print " $b_path adjust search path\n";
+ print " $b_deskint add menu items, shortcuts, etc.\n";
+ print " [$vars{'option_file_assocs'}] update file associations\n";
+ if (admin()) {
+ print " $b_admin make installation available to all users\n";
+ }
+ }
+ print " $b_addoneditor install TeXworks front end\n";
+ print " $b_path create symlinks to standard directories\n" unless
+ ($vars{'portable'} || win32());
+ }
+
+ if ($vars{'portable'}) {
+ print "\n <V> set up for regular hd installation\n";
+ } else {
+ print "\n <V> set up for portable installation\n";
+ }
+
+ other_options qw(I H Q);
+ my $answer = prompt 'Enter command';
+
+ if (defined $command{"\u$answer"}) {
+ return $command{"\u$answer"};
+ } else {
+ print "Unknown command: $answer\n\n";
+ return $command{'self'};
+ }
+}
+
+# needs a terminal 1 for require to succeed!
+1;
+
+__END__
+
+### Local Variables:
+### perl-indent-level: 2
+### tab-width: 2
+### indent-tabs-mode: nil
+### End:
+# vim:set tabstop=2 expandtab: #