From b0da09297c3b692c4581845ef4d6dd04171ab419 Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Tue, 24 Nov 2009 03:19:31 +0000 Subject: move the stuff to the menubar, all functional now git-svn-id: svn://tug.org/texlive/trunk@16149 c570f23f-e606-0410-a88d-b1316a301751 --- Master/tlpkg/dev/tlmgrgui2-withtabs.pl | 1532 ++++++++++++++++++++++++++++++++ Master/tlpkg/dev/tlmgrgui2.pl | 1064 +++++++++++++++++++--- 2 files changed, 2450 insertions(+), 146 deletions(-) create mode 100644 Master/tlpkg/dev/tlmgrgui2-withtabs.pl (limited to 'Master/tlpkg') diff --git a/Master/tlpkg/dev/tlmgrgui2-withtabs.pl b/Master/tlpkg/dev/tlmgrgui2-withtabs.pl new file mode 100644 index 00000000000..1e683d8f255 --- /dev/null +++ b/Master/tlpkg/dev/tlmgrgui2-withtabs.pl @@ -0,0 +1,1532 @@ +#!/usr/bin/env perl +# $Id: tlmgrgui2.pl 15823 2009-10-18 01:41:28Z preining $ +# +# Copyright 2009 Norbert Preining +# This file is licensed under the GNU General Public License version 2 +# or any later version. +# +# GUI for tlmgr +# version 2, completely rewritten GUI +# +# TODO: move the check for critical updates from old create_update_list +# to here!! +# TODO: center checkbuttons vertically +# TODO: double click on one line should pop up a window with tlmgr show info + +$^W = 1; +use strict; + +use Tk; +use Tk::Dialog; +use Tk::BrowseEntry; +use Tk::ROText; +use Tk::TixGrid; +use TeXLive::Splashscreen; + +use TeXLive::TLUtils qw(setup_programs platform_desc win32 debug); +use TeXLive::TLConfig; + +our $Master; +our $tlmediatlpdb; +our $tlmediasrc; +our $localtlpdb; + +# defined in tlmgr.pl +our $location; + +my $tlpdb_location; +my $cmdline_location; +# +our %opts; +# +# the list of packages as shown by TixGrid +# +my %Packages; +our $mw; + +sub update_status_box { + update_status(join(" ", @_)); + $mw->update; +} + +sub init_hooks { + push @::info_hook, \&update_status_box; + push @::warn_hook, \&update_status_box; + push @::debug_hook, \&update_status_box; + push @::ddebug_hook, \&update_status_box; + push @::dddebug_hook, \&update_status_box; +} + +sub update_status { + my ($p) = @_; + $::progressw->insert("end", "$p"); + $::progressw->see("end"); +} + + +# prepare for loading of lang.pl which expects $::lang and $::opt_lang +$::opt_lang = $opts{"gui-lang"} if (defined($opts{"gui-lang"})); + +require("TeXLive/trans.pl"); + +our @update_function_list; + +$mw = MainWindow->new; +$mw->title("TeX Live Manager $TeXLive::TLConfig::ReleaseYear"); +$mw->withdraw; + +# +# default layout definitions +# +# priority 20 = widgetDefault +# see Mastering Perl/Tk, 16.2. Using the Option Database +$mw->optionAdd("*Button.Relief", "ridge", 20); +# +# does not work, makes all buttons exactely 10, which is not a good idea +# I would like to have something like MinWidth 10... +#$mw->optionAdd("*Button.Width", "10", 20); +# +# shortcuts for padding, expand/fill, and pack sides, anchors +my @p_ii = qw/-padx 2m -pady 2m/; +my @p_iii= qw/-padx 3m -pady 3m/; +my @x_x = qw/-expand 1 -fill x/; +my @x_y = qw/-expand 1 -fill y/; +my @x_xy= qw/-expand 1 -fill both/; +my @left = qw/-side left/; +my @right= qw/-side right/; +my @bot = qw/-side bottom/; +my @a_w = qw/-anchor w/; +my @a_c = qw/-anchor c/; + + +# create a progress bar window +$::progressw = $mw->Scrolled("ROText", -scrollbars => "e", -height => 4); +$::progressw->pack(-fill => "x", @bot); + + +my $critical_updates_present = 0; + + +init_hooks(); + +info(__("Loading local TeX Live Database\nThis may take some time, please wait!") . "\n"); + +our $localtlmedia = TeXLive::TLMedia->new ( $Master ); +die("cannot setup TLMedia in $Master") unless (defined($localtlmedia)); +$localtlpdb = $localtlmedia->tlpdb; +die("cannot find tlpdb!") unless (defined($localtlpdb)); + +our @main_list; + +$tlpdb_location = $localtlpdb->option("location"); +if (defined($opts{"location"})) { + $cmdline_location = $opts{"location"}; +} + + +push @update_function_list, \&check_location_on_ctan; +push @update_function_list, \&init_install_media; + +# +# check that we can actually save the database +# +if (check_on_writable()) { + $::we_can_save = 1; +} else { + $::we_can_save = 0; + # here we should pop up a warning window!!! +} +$::action_button_state = ($::we_can_save ? "normal" : "disabled"); + +my $tlmgrrev = give_version(); +chomp($tlmgrrev); + +our $top = $mw->Frame; + +my $menu = $mw->Menu(); +my $menu_file = $menu->Menu(); +my $menu_options = $menu->Menu(); +my $menu_actions = $menu->Menu(); +my $menu_help = $menu->Menu(); +$menu->add('cascade', -label => "File", -menu => $menu_file); +$menu->add('cascade', -label => "Options", -menu => $menu_options); +$menu->add('cascade', -label => "Actions", -menu => $menu_actions); +$menu->add('cascade', -label => "Help", -menu => $menu_help); +$menu->add('separator'); +$menu->add('command', -label => "Loaded repository: none", + -command => sub { $location = $tlpdb_location; + update_loaded_location_string(); + run_update_functions(); + }); +# -activebackground => $menu->cget(-background)); + +# +# FILE MENU +# +$menu_file->add('command', -label => "Load default repository: $tlpdb_location", + -command => sub { + $location = $tlpdb_location; + update_loaded_location_string(); + run_update_functions(); + }); +if (defined($cmdline_location)) { + $menu_file->add('command', -label => "Load cmd line repository: $cmdline_location", + -command => sub { + $location = $cmdline_location; + update_loaded_location_string(); + run_update_functions(); + }); +} +$menu_file->add('command', -label => "Load default net repository: $TeXLiveURL", + -command => sub { + $location = $TeXLiveURL; + update_loaded_location_string(); + run_update_functions(); + }); +$menu_file->add('command', -label => "Load other repository", + -command => sub { menu_edit_location(); }); +$menu_file->add('separator'); +$menu_file->add('command', -label => __("Quit"), + -command => sub { $mw->destroy; exit(0); }); + +# +# OPTIONS MENU +# +$menu_options->add('command', -label => __("General settings"), + -command => sub { do_general_settings(); }); +$menu_options->add('command', -label => __("Paper settings"), + -command => sub { do_paper_settings(); }); +$menu_options->add('command', -label => __("Arch settings"), + -command => sub { do_arch_settings(); }); +$menu_options->add('separator'); +$menu_options->add('checkbutton', -label => __("Debug"), + -onvalue => ($::opt_verbosity == 0 ? 1 : $::opt_verbosity), + -variable => \$::opt_verbosity); + +# +# Actions menu +# +$menu_actions->add('command', -label => __("Re-initialize file database"), + -state => $::action_button_state, + -command => sub { + $mw->Busy(-recurse => 1); + info("Running mktexlsr, this may take some time ...\n"); + info(`mktexlsr 2>&1`); + $mw->Unbusy; + }); +$menu_actions->add('command', -label => __("Re-create all formats"), + -state => $::action_button_state, + -command => sub { + $mw->Busy(-recurse => 1); + info("Running fmtutil-sys --all, this may take some time ...\n"); + info(`fmtutil-sys --all 2>&1`); + $mw->Unbusy; + }); +$menu_actions->add('command', -label => __("Update font map database"), + -state => $::action_button_state, + -command => sub { + $mw->Busy(-recurse => 1); + info("Running updmap-sys, this may take some time ...\n"); + info(`updmap-sys 2>&1`); + $mw->Unbusy; + }); + +if (!win32()) { + $menu_actions->add('command', -label => __("Update symbolic links"), + -state => $::action_button_state, + -command => sub { + $mw->Busy(-recurse => 1); + info("Updating symlinks ...\n"); + execute_action_gui("path", "add"); + $mw->Unbusy; + }); + $menu_actions->add('command', -label => __("Remove symbolic links"), + -state => $::action_button_state, + -command => sub { + $mw->Busy(-recurse => 1); + info("Removing symlinks ...\n"); + execute_action_gui("path", "remove"); + $mw->Unbusy; + }); +} +if (!win32()) { + $menu_actions->add('separator'); + $menu_actions->add('command', -label => __("Remove TeX Live %s", $TeXLive::TLConfig::ReleaseYear), + -state => $::action_button_state, + -command => sub { + my $sw = $mw->DialogBox(-title => __("Remove TeX Live %s", $TeXLive::TLConfig::ReleaseYear), + -buttons => [ __("Ok"), __("Cancel") ], + -cancel_button => __("Cancel"), + -command => sub { + my $b = shift; + if ($b eq __("Ok")) { + system("tlmgr", "uninstall", "--force"); + $mw->Dialog(-text => __("Complete removal completed"), -buttons => [ __("Ok") ])->Show; + $mw->destroy; + exit(0); + } + }); + $sw->add("Label", -text => __("Really remove the complete TeX Live %s installation?\nYour last chance to change your mind!", $TeXLive::TLConfig::ReleaseYear))->pack(@p_iii); + $sw->Show; + }); +} + + + +# +# HELP MENU +$menu_help->add('command', -label => __("About"), + -command => sub { + my $sw = $mw->DialogBox(-title => __("About"), + -buttons => [ __("Ok") ]); + $sw->add("Label", -text => "TeX Live Manager (GUIv2) +$tlmgrrev +Copyright 2009 Norbert Preining + +Licensed under the GNU General Public License version 2 or higher +In case of problems, please contact: texlive\@tug.org" + )->pack(@p_iii); + $sw->Show; + }); + + +$mw->configure(-menu => $menu); + +our $back_f1 = $mw->Frame(); + +# pack .top .back -side top -fill both -expand 1 +$top->pack(-fill => 'x', @p_ii); +$back_f1->pack(@x_xy); + +#require ("do_listframe.pl"); + +######### SHOULD GO INTO A SEPARTE FILE ######################## +# install screen +my $top_frame = $back_f1->Labelframe(-text => "Display configuration"); +$top_frame->pack(@x_x, @p_ii); + +my $filter_frame = $top_frame->Frame(); +$filter_frame->pack; + +my $filter_status = $filter_frame->Labelframe(-text => "Status"); +$filter_status->pack(@left, @p_ii); + +my $status_all = 0; +my $status_only_installed = 1; +my $status_only_not_installed = 2; +my $status_only_updated = 3; +my $status_value = 0; +$filter_status->Radiobutton(-text => "all", + -variable => \$status_value, -value => $status_all)->pack(@a_w); +$filter_status->Radiobutton(-text => "only installed", + -variable => \$status_value, -value => $status_only_installed)->pack(@a_w); +$filter_status->Radiobutton(-text => "only uninstalled", + -variable => \$status_value, -value => $status_only_not_installed)->pack(@a_w); +$filter_status->Radiobutton(-text => "only updated", + -variable => \$status_value, -value => $status_only_updated)->pack(@a_w); + +my $filter_category = $filter_frame->Labelframe(-text => "Category"); +$filter_category->pack(@left, @x_y, @p_ii); +my $show_packages = 1; +my $show_collections = 1; +my $show_schemes = 1; +$filter_category->Checkbutton(-text => "packages", + -variable => \$show_packages)->pack(@a_w); +$filter_category->Checkbutton(-text => "collections", + -variable => \$show_collections)->pack(@a_w); +$filter_category->Checkbutton(-text => "schemes", + -variable => \$show_schemes)->pack(@a_w); + +my $filter_match = $filter_frame->Labelframe(-text => "Match"); +$filter_match->pack(@left, @x_y, @p_ii); +my $match_all = 1; +$filter_match->Radiobutton(-text => "all", + -variable => \$match_all, -value => 1)->pack(@a_w); +$filter_match->Radiobutton(-text => "matching:", + -variable => \$match_all, -value => 0)->pack(@a_w); +my $match_entry = + $filter_match->Entry(-width => 15)->pack(@a_w, -padx => '2m', @x_x); + +my $filter_selection = $filter_frame->Labelframe(-text => "Selection"); +$filter_selection->pack(@left, @x_y, @p_ii); +my $selection_value = 0; +$filter_selection->Radiobutton(-text => "all", + -variable => \$selection_value, -value => 0)->pack(@a_w); +$filter_selection->Radiobutton(-text => "only selected", + -variable => \$selection_value, -value => 1)->pack(@a_w); +$filter_selection->Radiobutton(-text => "only not selected", + -variable => \$selection_value, -value => 2)->pack(@a_w); + + +my $filter_button = $filter_frame->Labelframe(-text => "Action"); +$filter_button->pack(@left, @x_y, @p_ii); +$filter_button->Button(-text => "Apply filters", + -command => sub { update_grid(); })->pack(@a_c, @p_ii); +$filter_button->Button(-text => "Reset filters", + -command => sub { $status_value = $status_all; + $show_packages = 1; $show_collections = 1; + $show_schemes = 1; + $selection_value = 0; + $match_all = 1; + update_grid(); + })->pack(@a_c, @p_ii); + +########## Packages ####################### +my $list_frame = $back_f1->Labelframe(-text => "Packages"); +$list_frame->pack(@x_xy, @p_ii); +my $g = $list_frame->Scrolled('TixGrid', -scrollbars => "se", -bd => 0, + -floatingrows => 0, -floatingcols => 0, + -leftmargin => 2, # selection and label + -topmargin => 1, # top labels + -command => \&show_extended_info, # does not work, double click! + -selectmode => "none", + -selectunit => "row"); + +# that does not work, I have no idea what has to be done +#$g->ItemStyle('window', -anchor => "c"); + +$g->pack(qw/-expand 1 -fill both -padx 3 -pady 3/); +$g->configure(-formatcmd=>[\&AlternatingLineColoring, $g]); +$g->size(qw/col 4 -size 10char/); +$g->size(qw/col 5 -size 10char/); +$g->size(qw/col default -size auto/); +$g->size(qw/row default -size 1.1char -pad0 3/); + +setup_list(); +update_grid(); + +sub show_extended_info { + my ($x, $y) = @_; + print "double click on $x - $y\n"; +} + +sub update_grid { + # fill the header + #$g->set(0,0, -itemtype => 'window', -widget => $g->Checkbutton()); + $g->set(1,0, -itemtype => 'text', -text => "Package"); + $g->set(2,0, -itemtype => 'text', -text => "Local Rev"); + $g->set(3,0, -itemtype => 'text', -text => "Remote Rev"); + $g->set(4,0, -itemtype => 'text', -text => "Local Ver"); + $g->set(5,0, -itemtype => 'text', -text => "Remote Ver"); + $g->set(6,0, -itemtype => 'text', -text => "Short Desc"); + + my @schemes; + my @colls; + my @packs; + for my $p (sort keys %Packages) { + if ($Packages{$p}{'category'} eq "Scheme") { + push @schemes, $p; + } elsif ($Packages{$p}{'category'} eq "Collection") { + push @colls, $p; + } else { + push @packs, $p; + } + } + my $i = 1; + # the number of current lines: + my (undef, $curlines) = $g->index(0, 'max'); + for my $p (@schemes, @colls, @packs) { + if (MatchesFilters($p)) { + # unset first so that the checkbutton is unmapped, otherwise crashes + $g->unset(0,$i) if $g->infoExists(0,$i); + $g->set(0,$i, -itemtype => 'window', + -widget => $Packages{$p}{'cb'}); + # + $g->set(1,$i, -itemtype => 'text', -text => $Packages{$p}{'displayname'}); + if (defined($Packages{$p}{'localrevision'})) { + $g->set(2,$i, -itemtype => 'text', -text => $Packages{$p}{'localrevision'}); + } else { + $g->unset(2,$i); + } + if (defined($Packages{$p}{'remoterevision'})) { + $g->set(3,$i, -itemtype => 'text', -text => $Packages{$p}{'remoterevision'}) + } else { + $g->unset(3,$i); + } + if (defined($Packages{$p}{'localcatalogueversion'})) { + $g->set(4,$i, -itemtype => 'text', -text => $Packages{$p}{'localcatalogueversion'}) + } else { + $g->unset(4,$i); + } + if (defined($Packages{$p}{'remotecatalogueversion'})) { + $g->set(5,$i, -itemtype => 'text', -text => $Packages{$p}{'remotecatalogueversion'}) + } else { + $g->unset(5,$i); + } + $g->set(6,$i, -itemtype => 'text', -text => $Packages{$p}{'shortdesc'}); + $i++; + } + } + if ($i <= $curlines) { + # remove the rest of the lines + $g->deleteRow($i, $curlines); + } +} + +sub MatchesFilters { + my $p = shift; + # status + if (( ($status_value == $status_all) ) || + ( ($status_value == $status_only_installed) && + (defined($Packages{$p}{'installed'})) && + ($Packages{$p}{'installed'} == 1) ) || + ( ($status_value == $status_only_not_installed) && + ( !defined($Packages{$p}{'installed'}) || + ($Packages{$p}{'installed'} == 0)) ) || + ( ($status_value == $status_only_updated) && + (defined($Packages{$p}{'localrevision'})) && + (defined($Packages{$p}{'remoterevision'})) && + ($Packages{$p}{'localrevision'} < $Packages{$p}{'remoterevision'}))) { + # do nothing, more checks have to be done + } else { + return 0; + } + # category + if (($show_packages && ($Packages{$p}{'category'} eq 'Other')) || + ($show_collections && ($Packages{$p}{'category'} eq 'Collection')) || + ($show_schemes && ($Packages{$p}{'category'} eq 'Scheme')) ) { + # do nothing, more checks have to be done + } else { + return 0; + } + # match + if (!$match_all) { + my $r = $match_entry->get; + # check for match on string + my $t = $Packages{$p}{'shortdesc'}; + $t |= ""; + my $lt = $Packages{$p}{'longdesc'}; + $lt |= ""; + if (($p =~ m/$r/) || ($t =~ m/$r/) || ($lt =~ m/$r/)) { + # do nothing, more checks have to be done + } else { + return 0; + } + } + # selection + if ($selection_value == 0) { + # all -> maybe more checks + } elsif ($selection_value == 1) { + # only selected + if ($Packages{$p}{'selected'}) { + # do nothing, maybe more checks + } else { + # not selected package and only selected packages shown + return 0; + } + } else { + # only not selected + if ($Packages{$p}{'selected'}) { + # selected, but only not selected should be shown + return 0; + } # else do nothing + } + # + # if we come down to here the package matches + return 1; +} + + +sub AlternatingLineColoring { + my ($w, $area, @entbox) = @_; + if ($area eq 'main') { + # first format all cells + # no select background -selectbackground => 'lightblue', + $w->formatGrid( @entbox, -selectbackground => 'gray70', + -xon => 1, -xoff => 0, -yon => 1, -yoff => 0, + -relief => 'raised', -bd => 0, -filled => 1, -bg => 'gray70'); + # format odd lines 1,3,5,7, ... (counting starts at 0!!!) + $w->formatGrid( @entbox, -selectbackground => 'gray90', + -xon => 1, -xoff => 0, -yon => 1, -yoff => 1, + -relief => 'raised', -bd => 0, -filled => 1, -bg => 'gray90'); + } + if ($area eq 'y_margin') { + my ($ulx, $uly, $lrx, $lry) = @entbox; + # format the checkbuttons backgrounds + for my $i ($uly..$lry) { + if ($w->infoExists(0,$i)) { + my $cb = $w->entrycget(0, $i, "-window"); + $cb->configure(-background => (($i-$uly)%2 ? 'gray70' : 'gray90')); + } + } + # first format all cells + # no select background -selectbackground => 'lightblue', + $w->formatBorder( @entbox, -selectbackground => 'gray70', + -xon => 1, -xoff => 0, -yon => 1, -yoff => 0, + -relief => 'raised', -bd => 0, -filled => 1, -bg => 'gray70'); + # format odd lines 1,3,5,7, ... (counting starts at 0!!!) + $w->formatBorder( @entbox, -selectbackground => 'gray90', + -xon => 1, -xoff => 0, -yon => 1, -yoff => 1, + -relief => 'raised', -bd => 0, -filled => 1, -bg => 'gray90'); + } +} + +####### actions frame + +my $bot_frame = $back_f1->Labelframe(-text => "Actions"); +$bot_frame->pack(@x_x, @p_ii); + +my $actions_frame = $bot_frame->Frame; +$actions_frame->pack(); + +my $with_sel_frame = $actions_frame->Labelframe(-text => "with selected"); +$with_sel_frame->pack(@left, @p_ii); +my $action_apply_filter = 1; +$with_sel_frame->Label(-text => "with filters")->pack(@left, @p_ii); + +$with_sel_frame->Radiobutton(-text => "applied", + -variable => \$action_apply_filter, -value => 1)->pack(@left, @p_ii); +$with_sel_frame->Radiobutton(-text => "not applied", + -variable => \$action_apply_filter, -value => 0)->pack(@left, @p_ii); +$with_sel_frame->Button(-text => 'Install', + -state => $::action_button_state, + -command => sub { install_selected_packages(); } + )->pack(@left, @p_ii); +$with_sel_frame->Button(-text => 'Upgrade', + -state => $::action_button_state, + -command => sub { update_selected_packages(); } + )->pack(@left, @p_ii); +$with_sel_frame->Button(-text => 'Remove', + -state => $::action_button_state, + -command => sub { remove_selected_packages(); } + )->pack(@left, @p_ii); +$with_sel_frame->Button(-text => 'Backup', + -state => $::action_button_state, + -command => sub { backup_selected_packages(); } + )->pack(@left, @p_ii); + +my $with_all_frame = $actions_frame->Labelframe(-text => "with all"); +$with_all_frame->pack(@left, @p_ii); +$with_all_frame->Button(-text => 'Update all', + -state => $::action_button_state, + -command => sub { update_all_packages(); } + )->pack(@a_c,@left,@p_ii); + +######################## ARCH ########################### + +my @archsavail; +my @archsinstalled; +my %archs; +my $currentarch; + +sub init_archs { + if (!defined($tlmediatlpdb)) { + @archsavail = $localtlpdb->available_architectures; + } else { + @archsavail = $tlmediatlpdb->available_architectures; + } + $currentarch = $localtlmedia->platform(); + @archsinstalled = $localtlpdb->available_architectures; + foreach my $a (@archsavail) { + $archs{$a} = 0; + if (grep(/^$a$/,@archsinstalled)) { + $archs{$a} = 1; + } + } +} + + +sub do_arch_settings { + my $sw = $mw->Toplevel(-title => __("Select architectures to support")); + my %archsbuttons; + init_archs(); + $sw->transient($mw); + $sw->grab(); + my $subframe = $sw->Labelframe(-text => __("Select architectures to support")); + $subframe->pack(-fill => "both", -padx => "2m", -pady => "2m"); + foreach my $a (@archsavail) { + $archsbuttons{$a} = + $subframe->Checkbutton(-command => sub { check_on_removal($sw, $a); }, + -variable => \$archs{$a}, + -text => platform_desc($a) + )->pack(-anchor => 'w'); + } + my $arch_frame = $sw->Frame; + $arch_frame->pack(-padx => "10m", -pady => "5m"); + $arch_frame->Button(-text => __("Apply changes"), + -state => $::action_button_state, + -command => sub { apply_arch_changes(); $sw->destroy; })->pack(-side => 'left', -padx => "3m"); + $arch_frame->Button(-text => __("Cancel"), + -command => sub { $sw->destroy; })->pack(-side => 'left', -padx => "3m"); +} + +sub check_on_removal { + my $arch_frame = shift; + my $a = shift; + if (!$archs{$a} && $a eq $currentarch) { + # removal not supported + $archs{$a} = 1; + $arch_frame->Dialog(-title => "info", + -text => __("Removals of the main architecture not possible!"), + -buttons => [ __("Ok") ])->Show; + } +} + +sub apply_arch_changes { + my @todo_add; + my @todo_remove; + foreach my $a (@archsavail) { + if (!$archs{$a} && grep(/^$a$/,@archsinstalled)) { + push @todo_remove, $a; + next; + } + if ($archs{$a} && !grep(/^$a$/,@archsinstalled)) { + push @todo_add, $a; + next; + } + } + if (@todo_add) { + execute_action_gui ( "arch", "add", @todo_add ); + } + if (@todo_remove) { + execute_action_gui ( "arch", "remove", @todo_remove ); + } + if (@todo_add || @todo_remove) { + reinit_local_tlpdb(); + init_archs(); + } +} + +########## CONFIG ################### +# +my @fileassocdesc; +$fileassocdesc[0] = __("None"); +$fileassocdesc[1] = __("Only new"); +$fileassocdesc[2] = __("All"); +my %defaults; +my %changeddefaults; + +sub init_defaults_setting { + for my $key (keys %TeXLive::TLConfig::TLPDBOptions) { + if ($TeXLive::TLConfig::TLPDBOptions{$key}->[0] eq "b") { + $defaults{$key} = ($localtlpdb->option($key) ? 1 : 0); + } else { + $defaults{$key} = $localtlpdb->option($key); + } + } +} + +sub do_general_settings { + my $sw = $mw->Toplevel(-title => __("Default settings")); + $sw->transient($mw); + $sw->grab(); + init_defaults_setting(); + %changeddefaults = (); + for my $k (keys %defaults) { + $changeddefaults{$k}{'value'} = $defaults{$k}; + if ($TeXLive::TLConfig::TLPDBOptions{$k}->[0] eq "b") { + $changeddefaults{$k}{'display'} = ($defaults{$k} ? __("Yes") : __("No")); + } else { + if ($k eq "file_assocs") { + $changeddefaults{$k}{'display'} = $fileassocdesc[$defaults{$k}]; + } else { + $changeddefaults{$k}{'display'} = $defaults{$k}; + } + } + } + + my @config_set_l; + my @config_set_m; + my @config_set_r; + + my $back_config_set = $sw->Labelframe(-text => __("Default settings")); + my $back_config_buttons = $sw->Frame(); + $back_config_set->pack(-fill => "both", -padx => "2m", -pady => "2m"); + + push @config_set_l, + $back_config_set->Label(-text => __("Default package repository"), -anchor => "w"); + push @config_set_m, + $back_config_set->Label(-textvariable => \$changeddefaults{"location"}{'display'}); + push @config_set_r, + $back_config_set->Button(-text => __("Change"), + -command => sub { menu_default_location($sw); }); + + + push @config_set_l, + $back_config_set->Label(-text => __("Create formats on installation"), -anchor => "w"); + push @config_set_m, + $back_config_set->Label(-textvariable => \$changeddefaults{"create_formats"}{'display'}); + push @config_set_r, + $back_config_set->Button(-text => __("Toggle"), + -command => sub { toggle_setting("create_formats"); }); + + push @config_set_l, + $back_config_set->Label(-text => __("Install macro/font sources"), -anchor => "w"); + push @config_set_m, + $back_config_set->Label(-textvariable => \$changeddefaults{"install_srcfiles"}{'display'}); + push @config_set_r, + $back_config_set->Button(-text => __("Toggle"), + -command => sub { toggle_setting("install_srcfiles"); }); + + push @config_set_l, + $back_config_set->Label(-text => __("Install macro/font docs"), -anchor => "w"); + push @config_set_m, + $back_config_set->Label(-textvariable => \$changeddefaults{"install_docfiles"}{'display'}); + push @config_set_r, + $back_config_set->Button(-text => __("Toggle"), + -command => sub { toggle_setting("install_docfiles"); }); + + push @config_set_l, + $back_config_set->Label(-text => __("Default backup directory"), -anchor => "w"); + push @config_set_m, + $back_config_set->Label(-textvariable => \$changeddefaults{"backupdir"}{'display'}); + push @config_set_r, + $back_config_set->Button(-text => __("Change"), + -command => sub { + my $dir = $sw->chooseDirectory(); + if (defined($dir) && ($defaults{"backupdir"} ne $dir)) { + # see warning concerning UTF8 or other encoded dir names!! + $changeddefaults{"backupdir"}{'value'} = $dir; + $changeddefaults{"backupdir"}{'display'} = $dir; + } + }); + + push @config_set_l, + $back_config_set->Label(-text => __("Auto backup setting"), -anchor => "w"); + push @config_set_m, + $back_config_set->Label(-textvariable => \$changeddefaults{"autobackup"}{'display'}); + push @config_set_r, + $back_config_set->Button(-text => __("Change"), + -command => sub { select_autobackup($sw); }, -anchor => "w"); + + if (!win32()) { + push @config_set_l, + $back_config_set->Label(-text => __("Link destination for programs"), -anchor => "w"); + push @config_set_m, + $back_config_set->Label(-textvariable => \$changeddefaults{"sys_bin"}{'display'}); + push @config_set_r, + $back_config_set->Button(-text => __("Change"), + -command => sub { + my $dir = $sw->chooseDirectory(); + if (defined($dir) && ($defaults{"sys_bin"} ne $dir)) { + # see warning concerning UTF8 or other encoded dir names!! + $changeddefaults{"sys_bin"}{'value'} = $dir; + $changeddefaults{"sys_bin"}{'display'} = $dir; + } + }); + + push @config_set_l, + $back_config_set->Label(-text => __("Link destination for info docs"), -anchor => "w"); + push @config_set_m, + $back_config_set->Label(-textvariable => \$changeddefaults{"sys_info"}{'display'}); + push @config_set_r, + $back_config_set->Button(-text => __("Change"), + -command => sub { + my $dir = $sw->chooseDirectory(); + if (defined($dir) && ($defaults{"sys_info"} ne $dir)) { + # see warning concerning UTF8 or other encoded dir names!! + $changeddefaults{"sys_info"}{'value'} = $dir; + $changeddefaults{"sys_info"}{'display'} = $dir; + } + }); + + push @config_set_l, + $back_config_set->Label(-text => __("Link destination for man pages"), -anchor => "w"); + push @config_set_m, + $back_config_set->Label(-textvariable => \$changeddefaults{"sys_man"}{'display'}); + push @config_set_r, + $back_config_set->Button(-text => __("Change"), + -command => sub { + my $dir = $sw->chooseDirectory(); + if (defined($dir) && ($defaults{"sys_man"} ne $dir)) { + # see warning concerning UTF8 or other encoded dir names!! + $changeddefaults{"sys_man"}{'value'} = $dir; + $changeddefaults{"sys_man"}{'display'} = $dir; + } + }); + } + + if (win32()) { + push @config_set_l, + $back_config_set->Label(-text => __("Create shortcuts in menu and on desktop"), -anchor => "w"); + push @config_set_m, + $back_config_set->Label(-textvariable => \$changeddefaults{"desktop_integration"}{'display'}); + push @config_set_r, + $back_config_set->Button(-text => __("Toggle"), + -command => sub { toggle_setting("desktop_integration"); }); + + if (admin()) { + push @config_set_l, + $back_config_set->Label(-text => __("Install for all users"), -anchor => "w"); + push @config_set_m, + $back_config_set->Label(-textvariable => \$changeddefaults{"w32_multi_user"}{'display'}); + push @config_set_r, + $back_config_set->Button(-text => __("Toggle"), + -command => sub { toggle_setting("w32_multi_user"); }); + } + + push @config_set_l, + $back_config_set->Label(-text => __("Change file associations"), -anchor => "w"); + push @config_set_m, + $back_config_set->Label(-textvariable => \$changeddefaults{'file_assocs'}{'display'}); + push @config_set_r, + $back_config_set->Button(-text => __("Change"), + -command => sub { select_file_assocs($sw); }, -anchor => "w"); + + } + + for my $i (0..$#config_set_l) { + $config_set_l[$i]->grid( $config_set_m[$i], $config_set_r[$i], + -padx => "1m", -pady => "1m", -sticky => "nwe"); + } + + $back_config_buttons->pack(-padx => "10m", -pady => "5m"); + $back_config_buttons->Button(-text => __("Apply changes"), + -state => $::action_button_state, + -command => sub { apply_settings_changes(); $sw->destroy; })->pack(-side => 'left', -padx => "3m"); + $back_config_buttons->Button(-text => __("Cancel"), + -command => sub { $sw->destroy; })->pack(-side => 'left', -padx => "3m"); +} + +sub apply_settings_changes { + for my $k (keys %defaults) { + if ($defaults{$k} ne $changeddefaults{$k}{'value'}) { + $localtlpdb->option($k, $changeddefaults{$k}{'value'}); + } + } + $localtlpdb->save; +} + +######## PAPER ######### +my %papers; +my %currentpaper; +my %changedpaper; + +sub init_paper_xdvi { + if (!win32()) { + @{$papers{"xdvi"}} = TeXLive::TLPaper::get_paper_list("xdvi"); + $currentpaper{"xdvi"} = ${$papers{"xdvi"}}[0]; + } +} +sub init_paper_pdftex { + @{$papers{"pdftex"}} = TeXLive::TLPaper::get_paper_list("pdftex"); + $currentpaper{"pdftex"} = ${$papers{"pdftex"}}[0]; +} +sub init_paper_dvips { + @{$papers{"dvips"}} = TeXLive::TLPaper::get_paper_list("dvips"); + $currentpaper{"dvips"} = ${$papers{"dvips"}}[0]; +} +sub init_paper_dvipdfm { + @{$papers{"dvipdfm"}} = TeXLive::TLPaper::get_paper_list("dvipdfm"); + $currentpaper{"dvipdfm"} = ${$papers{"dvipdfm"}}[0]; +} +sub init_paper_context { + if (defined($localtlpdb->get_package("bin-context"))) { + @{$papers{"context"}} = TeXLive::TLPaper::get_paper_list("context"); + $currentpaper{"context"} = ${$papers{"context"}}[0]; + } +} +sub init_paper_dvipdfmx { + @{$papers{"dvipdfmx"}} = TeXLive::TLPaper::get_paper_list("dvipdfmx"); + $currentpaper{"dvipdfmx"} = ${$papers{"dvipdfmx"}}[0]; +} + +my %init_paper_subs; +$init_paper_subs{"xdvi"} = \&init_paper_xdvi; +$init_paper_subs{"pdftex"} = \&init_paper_pdftex; +$init_paper_subs{"dvips"} = \&init_paper_dvips; +$init_paper_subs{"context"} = \&init_paper_context; +$init_paper_subs{"dvipdfm"} = \&init_paper_dvipdfm; +$init_paper_subs{"dvipdfmx"} = \&init_paper_dvipdfmx; + +sub init_all_papers { + for my $p (keys %init_paper_subs) { + &{$init_paper_subs{$p}}(); + } +} + + +sub do_paper_settings { + init_all_papers(); + my $sw = $mw->Toplevel(-title => __("Paper settings")); + $sw->transient($mw); + $sw->grab(); + + %changedpaper = %currentpaper; + + my $lower = $sw->Frame; + $lower->pack(-fill => "both"); + + my $back_config_pap = $lower->Labelframe(-text => __("Paper settings")); + my $back_config_buttons = $sw->Frame(); + + + my $back_config_pap_l1 = $back_config_pap->Label(-text => __("Default paper for all"), -anchor => "w"); + my $back_config_pap_m1 = $back_config_pap->Button(-text => "A4", + -command => sub { change_paper("all", "a4"); }); + my $back_config_pap_r1 = $back_config_pap->Button(-text => "letter", + -command => sub { change_paper("all", "letter"); }); + + $back_config_pap_l1->grid( $back_config_pap_m1, $back_config_pap_r1, + -padx => "2m", -pady => "2m", -sticky => "nswe"); + + my (%l,%m,%r); + foreach my $p (sort keys %papers) { + if (($p eq "context") && !defined($localtlpdb->get_package("bin-context"))) { + next; + } + $l{$p} = $back_config_pap->Label(-text => __("Default paper for") . " $p", -anchor => "w"); + $m{$p} = $back_config_pap->Label(-textvariable => \$changedpaper{$p}, -anchor => "w"); + $r{$p} = $back_config_pap->Button(-text => __("Change"), + -command => sub { select_paper($sw,$p); }, -anchor => "w"); + $l{$p}->grid( $m{$p}, $r{$p}, + -padx => "2m", -pady => "2m", -sticky => "nsw"); +} + + $back_config_pap->pack(-side => 'left', -fill => "both", -padx => "2m", -pady => "2m"); + + $back_config_buttons->pack(-padx => "10m", -pady => "5m"); + $back_config_buttons->Button(-text => __("Apply changes"), + -state => $::action_button_state, + -command => sub { apply_paper_changes(); $sw->destroy; })->pack(-side => 'left', -padx => "3m"); + $back_config_buttons->Button(-text => __("Cancel"), + -command => sub { $sw->destroy; })->pack(-side => 'left', -padx => "3m"); +} + + +sub menu_default_location { + my $mw = shift; + my $val; + my $sw = $mw->Toplevel(-title => __("Change default package repository")); + $sw->transient($mw); + $sw->grab(); + $sw->Label(-text => __("New default package repository"))->pack(-padx => "2m", -pady => "2m"); + + my $f1 = $sw->Frame; + my $entry = $f1->Entry(-text => $val, -width => 50); + $entry->pack(-side => "left",-padx => "2m", -pady => "2m"); + + my $f2 = $sw->Frame; + $f2->Button(-text => __("Choose Directory"), + -command => sub { + my $var = $sw->chooseDirectory; + if (defined($var)) { + $entry->delete(0,"end"); + $entry->insert(0,$var); + } + })->pack(-side => "left",-padx => "2m", -pady => "2m"); + $f2->Button(-text => __("Default net package repository"), + -command => sub { + $entry->delete(0,"end"); + $entry->insert(0,$TeXLiveURL); + })->pack(-side => "left",-padx => "2m", -pady => "2m"); + $f1->pack; + $f2->pack; + + my $f = $sw->Frame; + my $okbutton = $f->Button(-text => __("Ok"), + -command => sub { $changeddefaults{'location'}{'value'} = + $changeddefaults{'location'}{'display'} = + $entry->get; + $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'); + $sw->bind('', [ $okbutton, 'Invoke' ]); + $sw->bind('', [ $cancelbutton, 'Invoke' ]); +} + +sub toggle_setting() { + my ($key) = @_; + my $old = $changeddefaults{$key}{'value'}; + my $new = ($old ? 0 : 1); + $changeddefaults{$key}{'display'} = ($new ? __("Yes") : __("No")); + $changeddefaults{$key}{'value'} = $new; +} + + +sub apply_paper_changes { + $mw->Busy(-recurse => 1); + for my $k (keys %changedpaper) { + if ($currentpaper{$k} ne $changedpaper{$k}) { + execute_action_gui ( "paper", $k, "paper", $changedpaper{$k}); + &{$init_paper_subs{$k}}(); + } + } + $mw->Unbusy; +} + +sub change_paper { + my ($prog, $pap) = @_; + if ($prog eq "all") { + for my $k (keys %changedpaper) { + $changedpaper{$k} = $pap; + } + } else { + $changedpaper{$prog} = $pap; + } +} + +sub select_paper { + my $back_config = shift; + my $prog = shift; + my $foo = $back_config->Toplevel(-title => __("Select paper format for") . " $prog"); + $foo->transient($back_config); + $foo->grab(); + my $var = $changedpaper{$prog}; + my $opt = $foo->BrowseEntry(-label => __("Default paper for") . " $prog", -variable => \$var); + foreach my $p (sort @{$papers{$prog}}) { + $opt->insert("end",$p); + } + $opt->pack(-padx => "2m", -pady => "2m"); + my $f = $foo->Frame; + my $okbutton = $f->Button(-text => __("Ok"), -command => sub { change_paper($prog,$var); $foo->destroy; })->pack(-side => "left", -padx => "2m", -pady => "2m"); + my $cancelbutton = $f->Button(-text => __("Cancel"), -command => sub { $foo->destroy; })->pack(-side => "left", -padx => "2m", -pady => "2m"); + $f->pack; + $foo->bind('', [ $okbutton, 'Invoke' ]); + $foo->bind('', [ $cancelbutton, 'Invoke' ]); +} + +sub select_autobackup { + my $mw = shift; + my $foo = $mw->Toplevel(-title => __("Auto backup setting")); + $foo->transient($mw); + $foo->grab(); + my $var = $defaults{"autobackup"}; + my $opt = $foo->BrowseEntry(-label => __("Auto backup setting"), + -variable => \$var); + my @al; + push @al, "-1 (" . __("keep arbitrarily many") . ")"; + push @al, "0 (" . __("disable") . ")"; + for my $i (1..100) { + push @al, $i; + } + foreach my $p (@al) { + $opt->insert("end",$p); + } + $opt->pack(-padx => "2m", -pady => "2m"); + my $f = $foo->Frame; + my $okbutton = $f->Button(-text => __("Ok"), + -command => sub { + $var =~ s/ .*$//; + $changeddefaults{"autobackup"}{'value'} = $var; + $changeddefaults{"autobackup"}{'display'} = $var; + $foo->destroy; + } + )->pack(-side => "left", -padx => "2m", -pady => "2m"); + my $cancelbutton = $f->Button(-text => __("Cancel"), -command => sub { $foo->destroy; })->pack(-side => "left", -padx => "2m", -pady => "2m"); + $f->pack; + $foo->bind('', [ $okbutton, 'Invoke' ]); + $foo->bind('', [ $cancelbutton, 'Invoke' ]); +} + + +sub select_file_assocs { + my $sw = shift; + my $foo = $sw->Toplevel(-title => __("Change file associations")); + $foo->transient($mw); + $foo->grab(); + my $var = $defaults{"file_assocs"}; + my $opt = $foo->BrowseEntry(-label => __("Change file associations"), + -variable => \$var); + my @al; + for my $i (0..2) { + push @al, "$i $fileassocdesc[$i]"; + } + foreach my $p (@al) { + $opt->insert("end",$p); + } + $opt->pack(-padx => "2m", -pady => "2m"); + my $f = $foo->Frame; + my $okbutton = $f->Button(-text => __("Ok"), + -command => sub { + $var = substr($var,0,1); + $changeddefaults{"file_assocs"}{'display'} = $fileassocdesc[$var]; + $changeddefaults{"file_assocs"}{'value'} = $var; + + $foo->destroy; + } + )->pack(-side => "left", -padx => "2m", -pady => "2m"); + my $cancelbutton = $f->Button(-text => __("Cancel"), -command => sub { $foo->destroy; })->pack(-side => "left", -padx => "2m", -pady => "2m"); + $f->pack; + $foo->bind('', [ $okbutton, 'Invoke' ]); + $foo->bind('', [ $cancelbutton, 'Invoke' ]); +} + + + +################ END FUNCTIONS + +if ($opts{"load"}) { + run_update_functions(); +} + + +info(__("Completed") . "\n"); +$mw->deiconify; + + +if (!$::we_can_save) { + my $no_write_warn = $mw->Dialog(-title => "warning", + -text => __("You don't have permissions to change the installation in any way,\nspecifically, the directory %s is not writable.\nPlease run this program as administrator, or contact your local admin.\n\nMost buttons will be disabled.", "$Master/tlpkg/"), + -buttons => [ __("Ok") ])->Show(); +} + +Tk::MainLoop(); + + +sub init_install_media { + my $newroot = $location; + if (defined($tlmediatlpdb) && ($tlmediatlpdb->root eq $newroot)) { + # nothing to be done + } else { + $mw->Busy(-recurse => 1); + info(__("Loading remote TeX Live Database\nThis may take some time, please wait!") . "\n"); + $tlmediasrc = TeXLive::TLMedia->new($newroot); + info(__("Completed") . "\n"); + $mw->Unbusy; + if (!defined($tlmediasrc)) { + # something went badly wrong, maybe the newroot is wrong? + $mw->Dialog(-title => "warning", + -text => __("Could not load the TeX Live Database from %s\nIf you want to install or update packages, please try with a different package repository!\n\nFor configuration and removal you don\'t have to do anything.", $newroot), + -buttons => [ __("Ok") ])->Show; + $tlmediatlpdb = undef; + $tlmediasrc = undef; + update_list_remote(); + update_grid(); + update_loaded_location_string("none"); + } else { + $tlmediatlpdb = $tlmediasrc->tlpdb; + update_list_remote(); + update_grid(); + } + } +} + +sub set_text_win { + my ($w, $t) = @_; + $w->delete("0.0", "end"); + $w->insert("0.0", "$t"); + $w->see("0.0"); +} + +sub install_selected_packages { + my @foo = SelectedPackages(); + if (@foo) { + my @args = qw/install/; + push @args, @foo; + execute_action_gui(@args); + reinit_local_tlpdb(); + # now we check that the installation has succeeded by checking that + # all packages in @_ are installed. Otherwise we pop up a warning window + my $do_warn = 0; + for my $p (@_) { + if (!defined($localtlpdb->get_package($p))) { + $do_warn = 1; + last; + } + } + give_warning_window(__("Installation"), @_) if $do_warn; + } +} + +sub SelectedPackages { + my @ret; + # first select those that are + for my $p (keys %Packages) { + next if !$Packages{$p}{'selected'}; + if ($action_apply_filter) { + if (MatchesFilters($p)) { + push @ret, $p; + } + } else { + push @ret, $p; + } + } + return @ret; +} + +sub update_all_packages { + my @args = qw/update/; + if ($critical_updates_present) { + $opts{"self"} = 1; + } else { + $opts{"all"} = 1; + } + execute_action_gui(qw/update/); + if ($critical_updates_present) { + # terminate here immediately so that we are sure the auto-updater + # is run immediately + # make sure we exit in finish(0) + $::gui_mode = 0; + finish(0); + } + reinit_local_tlpdb(); +} + +sub update_selected_packages { + my @foo = SelectedPackages(); + if (@foo) { + my @args = qw/update/; + # argument processing + # in case we have critical updates present we do put the list of + # critical updates into the argument instead of --all + if ($critical_updates_present) { + $opts{"self"} = 1; + } + push @args, @foo; + execute_action_gui(@args); + if ($critical_updates_present) { + # terminate here immediately so that we are sure the auto-updater + # is run immediately + # make sure we exit in finish(0) + $::gui_mode = 0; + finish(0); + } + reinit_local_tlpdb(); + } +} + +sub remove_selected_packages { + my @foo = SelectedPackages(); + if (@foo) { + my @args = qw/remove/; + push @args, @foo; + execute_action_gui(@args); + reinit_local_tlpdb(); + my $do_warn = 0; + for my $p (@_) { + if (defined($localtlpdb->get_package($p))) { + $do_warn = 1; + last; + } + } + give_warning_window(__("Remove"), @_) if $do_warn; + } +} + +sub backup_selected_packages { + my @foo = SelectedPackages(); + if (@foo) { + my @args = qw/backup/; + push @args, @foo; + execute_action_gui(@args); + } +} + +sub reinit_local_tlpdb { + $mw->Busy(-recurse => 1); + $localtlpdb = TeXLive::TLPDB->new ("root" => "$Master"); + die("cannot find tlpdb!") unless (defined($localtlpdb)); + setup_list(); + update_grid(); + $mw->Unbusy; +} + +# +# creates/updates the list of packages as shown in tix grid +# +sub setup_list { + my @do_later; + for my $p ($localtlpdb->list_packages()) { + # collect packages containing a . for later + # we want to ignore them in most cases but those where there is + # no father package (without .) + if ($p =~ m;\.;) { + push @do_later, $p; + next; + } + my $tlp = $localtlpdb->get_package($p); + # collect information about that package we will show + $Packages{$p}{'displayname'} = $p; + $Packages{$p}{'localrevision'} = $tlp->revision; + $Packages{$p}{'shortdesc'} = $tlp->shortdesc; + $Packages{$p}{'longdesc' } = $tlp->longdesc; + $Packages{$p}{'installed'} = 1; + $Packages{$p}{'selected'} = 0; + $Packages{$p}{'cb'} = $g->Checkbutton(-variable => \$Packages{$p}{'selected'}); + if (($tlp->category eq "Collection") || + ($tlp->category eq "Scheme")) { + $Packages{$p}{'category'} = $tlp->category; + } else { + $Packages{$p}{'category'} = "Other"; + } + if (defined($tlp->cataloguedata->{'version'})) { + $Packages{$p}{'localcatalogueversion'} = $tlp->cataloguedata->{'version'}; + } + } + for my $p (@do_later) { + my $s = $p; + $s =~ s!\.[^.]*$!!; + if (!defined($Packages{$s})) { + my $tlp = $localtlpdb->get_package($p); + # collect information about that package we will show + $Packages{$p}{'displayname'} = $p; + $Packages{$p}{'localrevision'} = $tlp->revision; + $Packages{$p}{'shortdesc'} = $tlp->shortdesc; + $Packages{$p}{'longdesc' } = $tlp->longdesc; + $Packages{$p}{'installed'} = 1; + $Packages{$p}{'selected'} = 0; + $Packages{$p}{'cb'} = $g->Checkbutton(-variable => \$Packages{$p}{'selected'}); + if (($tlp->category eq "Collection") || + ($tlp->category eq "Scheme")) { + $Packages{$p}{'category'} = $tlp->category; + } else { + $Packages{$p}{'category'} = "Other"; + } + if (defined($tlp->cataloguedata->{'version'})) { + $Packages{$p}{'localcatalogueversion'} = $tlp->cataloguedata->{'version'}; + } + } + } + update_list_remote(); +} + +sub update_list_remote { + my @do_later_media; + print "TODO move the check from critical_updates_present from the old sub create_update_list here!!!"; + # clear old info from remote media + for my $p (keys %Packages) { + if (!$Packages{$p}{'installed'}) { + delete $Packages{$p}; + next; + } + delete $Packages{$p}{'remoterevision'}; + delete $Packages{$p}{'remotecatalogueversion'}; + } + if (defined($tlmediatlpdb)) { + for my $p ($tlmediatlpdb->list_packages()) { + if ($p =~ m;\.;) { + push @do_later_media, $p; + next; + } + my $tlp = $tlmediatlpdb->get_package($p); + $Packages{$p}{'displayname'} = $p; + $Packages{$p}{'remoterevision'} = $tlp->revision; + # overwrite, we assume that the remove version is better ;-) + $Packages{$p}{'shortdesc'} = $tlp->shortdesc; + $Packages{$p}{'longdesc' } = $tlp->longdesc; + $Packages{$p}{'selected'} = 0 + unless defined $Packages{$p}{'selected'}; + $Packages{$p}{'cb'} = $g->Checkbutton(-variable => \$Packages{$p}{'selected'}) + unless defined $Packages{$p}{'cb'}; + if (($tlp->category eq "Collection") || + ($tlp->category eq "Scheme")) { + $Packages{$p}{'category'} = $tlp->category; + } else { + $Packages{$p}{'category'} = "Other"; + } + if (defined($tlp->cataloguedata->{'version'})) { + $Packages{$p}{'remotecatalogueversion'} = $tlp->cataloguedata->{'version'}; + } + } + } + for my $p (@do_later_media) { + my $s = $p; + $s =~ s!\.[^.]*$!!; + if (!defined($Packages{$s})) { + my $tlp = $tlmediatlpdb->get_package($p); + # collect information about that package we will show + $Packages{$p}{'displayname'} = $p; + $Packages{$p}{'remoterevision'} = $tlp->revision; + $Packages{$p}{'shortdesc'} = $tlp->shortdesc; + $Packages{$p}{'longdesc' } = $tlp->longdesc; + $Packages{$p}{'selected'} = 0 + unless defined $Packages{$p}{'selected'}; + $Packages{$p}{'cb'} = $g->Checkbutton(-variable => \$Packages{$p}{'selected'}) + unless defined $Packages{$p}{'cb'}; + if (($tlp->category eq "Collection") || + ($tlp->category eq "Scheme")) { + $Packages{$p}{'category'} = $tlp->category; + } else { + $Packages{$p}{'category'} = "Other"; + } + if (defined($tlp->cataloguedata->{'version'})) { + $Packages{$p}{'remotecatalogueversion'} = $tlp->cataloguedata->{'version'}; + } + } + } + # change display names + for my $p (keys %Packages) { + if ($p =~ m/^collection-documentation-(.*)$/) { + $Packages{$p}{'displayname'} = "collection-doc-$1"; + } + } +} + + +sub menu_edit_location { + my $key = shift; + my $val; + my $sw = $mw->Toplevel(-title => __("Load package repository")); + $sw->transient($mw); + $sw->grab(); + $sw->Label(-text => __("Package repository:"))->pack(@p_ii); + my $entry = $sw->Entry(-text => $location, -width => 30); + $entry->pack(); + my $f1 = $sw->Frame; + $f1->Button(-text => __("Choose Directory"), + -command => sub { + my $var = $sw->chooseDirectory; + if (defined($var)) { + $entry->delete(0,"end"); + $entry->insert(0,$var); + } + })->pack(@left, @p_ii); + $f1->Button(-text => __("Default net package repository"), + -command => sub { + $entry->delete(0,"end"); + $entry->insert(0,$TeXLiveURL); + })->pack(@left, @p_ii); + $f1->pack; + my $f = $sw->Frame; + my $okbutton = $f->Button(-text => __("Ok"), + -command => sub { $location = $entry->get; + $sw->destroy; + update_loaded_location_string(); + run_update_functions(); + })->pack(@left, @p_ii); + my $cancelbutton = $f->Button(-text => __("Cancel"), + -command => sub { $sw->destroy })->pack(@right, @p_ii); + $f->pack(-expand => 1); + $sw->bind('', [ $okbutton, 'Invoke' ]); + $sw->bind('', [ $cancelbutton, 'Invoke' ]); +} + +sub update_loaded_location_string { + my $arg = shift; + $arg || ($arg = $location); + $menu->entryconfigure('end', -label => "Loaded repository: $arg"); +} + +sub run_update_functions { + foreach my $f (@update_function_list) { + &{$f}(); + } +} + +sub check_location_on_ctan { + # we want to check that if mirror.ctan.org + # is used that we select a mirror once + if ($location =~ m/$TeXLive::TLConfig::TeXLiveServerURL/) { + $location = TeXLive::TLUtils::give_ctan_mirror(); + } +} + +sub execute_action_gui { + $mw->Busy(-recurse => 1); + info ("Executing action @_\n"); + execute_action(@_); + info(__("Completed") . "\n"); + $mw->Unbusy; +} + +sub give_warning_window { + my ($act, @args) = @_; + my $sw = $mw->DialogBox(-title => __("Warning Window"), -buttons => [ __("Ok") ]); + $sw->add("Label", -text => __("Running %s failed.\nPlease consult the log window for details.", "$act @args") + )->pack(@p_iii); + $sw->Show; +} + +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/dev/tlmgrgui2.pl b/Master/tlpkg/dev/tlmgrgui2.pl index 70bf1a0c8cd..1e683d8f255 100644 --- a/Master/tlpkg/dev/tlmgrgui2.pl +++ b/Master/tlpkg/dev/tlmgrgui2.pl @@ -6,13 +6,20 @@ # or any later version. # # GUI for tlmgr +# version 2, completely rewritten GUI +# +# TODO: move the check for critical updates from old create_update_list +# to here!! +# TODO: center checkbuttons vertically +# TODO: double click on one line should pop up a window with tlmgr show info + +$^W = 1; +use strict; use Tk; use Tk::Dialog; -use Tk::NoteBook; use Tk::BrowseEntry; use Tk::ROText; -use Tk::Balloon; use Tk::TixGrid; use TeXLive::Splashscreen; @@ -22,13 +29,20 @@ use TeXLive::TLConfig; our $Master; our $tlmediatlpdb; our $tlmediasrc; +our $localtlpdb; + +# defined in tlmgr.pl our $location; + +my $tlpdb_location; +my $cmdline_location; # our %opts; # # the list of packages as shown by TixGrid # my %Packages; +our $mw; sub update_status_box { update_status(join(" ", @_)); @@ -49,8 +63,6 @@ sub update_status { $::progressw->see("end"); } -my $opt_screen = $::guiscreen; - # prepare for loading of lang.pl which expects $::lang and $::opt_lang $::opt_lang = $opts{"gui-lang"} if (defined($opts{"gui-lang"})); @@ -59,7 +71,7 @@ require("TeXLive/trans.pl"); our @update_function_list; -our $mw = MainWindow->new; +$mw = MainWindow->new; $mw->title("TeX Live Manager $TeXLive::TLConfig::ReleaseYear"); $mw->withdraw; @@ -92,6 +104,9 @@ $::progressw = $mw->Scrolled("ROText", -scrollbars => "e", -height => 4); $::progressw->pack(-fill => "x", @bot); +my $critical_updates_present = 0; + + init_hooks(); info(__("Loading local TeX Live Database\nThis may take some time, please wait!") . "\n"); @@ -103,16 +118,11 @@ die("cannot find tlpdb!") unless (defined($localtlpdb)); our @main_list; -my $loc = $localtlpdb->option("location"); -if (defined($loc)) { - $location = $loc; -} +$tlpdb_location = $localtlpdb->option("location"); if (defined($opts{"location"})) { - $location = $opts{"location"}; + $cmdline_location = $opts{"location"}; } -our $balloon = $mw->Balloon(); - push @update_function_list, \&check_location_on_ctan; push @update_function_list, \&init_install_media; @@ -128,76 +138,170 @@ if (check_on_writable()) { } $::action_button_state = ($::we_can_save ? "normal" : "disabled"); +my $tlmgrrev = give_version(); +chomp($tlmgrrev); + our $top = $mw->Frame; -our $top_top = $top->Frame; -our $top_bot = $top->Frame; -$top_top->pack(@x_x); -$top_bot->pack(@x_x); +my $menu = $mw->Menu(); +my $menu_file = $menu->Menu(); +my $menu_options = $menu->Menu(); +my $menu_actions = $menu->Menu(); +my $menu_help = $menu->Menu(); +$menu->add('cascade', -label => "File", -menu => $menu_file); +$menu->add('cascade', -label => "Options", -menu => $menu_options); +$menu->add('cascade', -label => "Actions", -menu => $menu_actions); +$menu->add('cascade', -label => "Help", -menu => $menu_help); +$menu->add('separator'); +$menu->add('command', -label => "Loaded repository: none", + -command => sub { $location = $tlpdb_location; + update_loaded_location_string(); + run_update_functions(); + }); +# -activebackground => $menu->cget(-background)); -our $quit = $top_top->Button(-text => __("Quit"), - -command => sub { $mw->destroy; exit(0); }); +# +# FILE MENU +# +$menu_file->add('command', -label => "Load default repository: $tlpdb_location", + -command => sub { + $location = $tlpdb_location; + update_loaded_location_string(); + run_update_functions(); + }); +if (defined($cmdline_location)) { + $menu_file->add('command', -label => "Load cmd line repository: $cmdline_location", + -command => sub { + $location = $cmdline_location; + update_loaded_location_string(); + run_update_functions(); + }); +} +$menu_file->add('command', -label => "Load default net repository: $TeXLiveURL", + -command => sub { + $location = $TeXLiveURL; + update_loaded_location_string(); + run_update_functions(); + }); +$menu_file->add('command', -label => "Load other repository", + -command => sub { menu_edit_location(); }); +$menu_file->add('separator'); +$menu_file->add('command', -label => __("Quit"), + -command => sub { $mw->destroy; exit(0); }); -my $tlmgrrev = give_version(); -chomp($tlmgrrev); -our $about = $top_top->Button(-text => __("About"), +# +# OPTIONS MENU +# +$menu_options->add('command', -label => __("General settings"), + -command => sub { do_general_settings(); }); +$menu_options->add('command', -label => __("Paper settings"), + -command => sub { do_paper_settings(); }); +$menu_options->add('command', -label => __("Arch settings"), + -command => sub { do_arch_settings(); }); +$menu_options->add('separator'); +$menu_options->add('checkbutton', -label => __("Debug"), + -onvalue => ($::opt_verbosity == 0 ? 1 : $::opt_verbosity), + -variable => \$::opt_verbosity); + +# +# Actions menu +# +$menu_actions->add('command', -label => __("Re-initialize file database"), + -state => $::action_button_state, + -command => sub { + $mw->Busy(-recurse => 1); + info("Running mktexlsr, this may take some time ...\n"); + info(`mktexlsr 2>&1`); + $mw->Unbusy; + }); +$menu_actions->add('command', -label => __("Re-create all formats"), + -state => $::action_button_state, + -command => sub { + $mw->Busy(-recurse => 1); + info("Running fmtutil-sys --all, this may take some time ...\n"); + info(`fmtutil-sys --all 2>&1`); + $mw->Unbusy; + }); +$menu_actions->add('command', -label => __("Update font map database"), + -state => $::action_button_state, + -command => sub { + $mw->Busy(-recurse => 1); + info("Running updmap-sys, this may take some time ...\n"); + info(`updmap-sys 2>&1`); + $mw->Unbusy; + }); + +if (!win32()) { + $menu_actions->add('command', -label => __("Update symbolic links"), + -state => $::action_button_state, + -command => sub { + $mw->Busy(-recurse => 1); + info("Updating symlinks ...\n"); + execute_action_gui("path", "add"); + $mw->Unbusy; + }); + $menu_actions->add('command', -label => __("Remove symbolic links"), + -state => $::action_button_state, + -command => sub { + $mw->Busy(-recurse => 1); + info("Removing symlinks ...\n"); + execute_action_gui("path", "remove"); + $mw->Unbusy; + }); +} +if (!win32()) { + $menu_actions->add('separator'); + $menu_actions->add('command', -label => __("Remove TeX Live %s", $TeXLive::TLConfig::ReleaseYear), + -state => $::action_button_state, + -command => sub { + my $sw = $mw->DialogBox(-title => __("Remove TeX Live %s", $TeXLive::TLConfig::ReleaseYear), + -buttons => [ __("Ok"), __("Cancel") ], + -cancel_button => __("Cancel"), + -command => sub { + my $b = shift; + if ($b eq __("Ok")) { + system("tlmgr", "uninstall", "--force"); + $mw->Dialog(-text => __("Complete removal completed"), -buttons => [ __("Ok") ])->Show; + $mw->destroy; + exit(0); + } + }); + $sw->add("Label", -text => __("Really remove the complete TeX Live %s installation?\nYour last chance to change your mind!", $TeXLive::TLConfig::ReleaseYear))->pack(@p_iii); + $sw->Show; + }); +} + + + +# +# HELP MENU +$menu_help->add('command', -label => __("About"), -command => sub { - my $sw = $mw->DialogBox(-title => __("About"), + my $sw = $mw->DialogBox(-title => __("About"), -buttons => [ __("Ok") ]); - $sw->add("Label", -text => "TeX Live Manager + $sw->add("Label", -text => "TeX Live Manager (GUIv2) $tlmgrrev -Copyright 2008 Tomasz Luczak -Copyright 2008, 2009 Norbert Preining +Copyright 2009 Norbert Preining Licensed under the GNU General Public License version 2 or higher In case of problems, please contact: texlive\@tug.org" )->pack(@p_iii); $sw->Show; }); + -$about->pack(@right); -$quit->pack(@right); - -$mw->bind('', [ $quit, 'Invoke' ]); - - -$top_top->Label(-text => __("Repository to use") . " ")->pack(@left); -$top_bot->Button(-text => __("Load default"), - -command => sub { run_update_functions(); })->pack(@left); -$top_bot->Button(-text => __("Load other"), - -command => sub { menu_edit_location(); })->pack(@left); -$top_bot->Label(-text => __("Loaded repository:") . " ")->pack(@left); -$top_bot->Label(-textvariable => \$location)->pack(@left); - - - -# here we add a bit of trickery to make sure that the verbosity level -# as set on the cmd line (-v or -v -v) is kept during pressing the -# debug button on and off. If -v is *not* given activating it afterwards -# defaults to one -v, while if -v -v is given on the cmd line, we keep -# it that way -$balloon->attach( - $top_bot->Checkbutton(-text => __("Debug"), - -onvalue => ($::opt_verbosity == 0 ? 1 : $::opt_verbosity), - -variable => \$::opt_verbosity)->pack(@right), - -balloonmsg => __("Turn on debug mode.")); - -# frame .back -borderwidth 2 -our $back = $mw->NoteBook(-borderwidth => 2, -dynamicgeometry => 1); +$mw->configure(-menu => $menu); +our $back_f1 = $mw->Frame(); # pack .top .back -side top -fill both -expand 1 $top->pack(-fill => 'x', @p_ii); -$back->pack(@x_xy); +$back_f1->pack(@x_xy); #require ("do_listframe.pl"); ######### SHOULD GO INTO A SEPARTE FILE ######################## # install screen -our $back_f1 = $back->add("packages",-label => __("Packages"), -justify => "left"); - -$screens{"packages"} = $back_f1; - my $top_frame = $back_f1->Labelframe(-text => "Display configuration"); $top_frame->pack(@x_x, @p_ii); @@ -235,12 +339,13 @@ $filter_category->Checkbutton(-text => "schemes", my $filter_match = $filter_frame->Labelframe(-text => "Match"); $filter_match->pack(@left, @x_y, @p_ii); -my $match_value = 0; +my $match_all = 1; $filter_match->Radiobutton(-text => "all", - -variable => \$match_value, -value => 0)->pack(@a_w); + -variable => \$match_all, -value => 1)->pack(@a_w); $filter_match->Radiobutton(-text => "matching:", - -variable => \$match_value, -value => 1)->pack(@a_w); -$filter_match->Entry(-width => 15)->pack(@a_w, -padx => '2m', @x_x); + -variable => \$match_all, -value => 0)->pack(@a_w); +my $match_entry = + $filter_match->Entry(-width => 15)->pack(@a_w, -padx => '2m', @x_x); my $filter_selection = $filter_frame->Labelframe(-text => "Selection"); $filter_selection->pack(@left, @x_y, @p_ii); @@ -259,10 +364,10 @@ $filter_button->Button(-text => "Apply filters", -command => sub { update_grid(); })->pack(@a_c, @p_ii); $filter_button->Button(-text => "Reset filters", -command => sub { $status_value = $status_all; - $show_packages = 1; $show_collections = 1; - $show_schemes = 1; $show_tlcore = 1; + $show_packages = 1; $show_collections = 1; + $show_schemes = 1; $selection_value = 0; - $match_value = 0; + $match_all = 1; update_grid(); })->pack(@a_c, @p_ii); @@ -273,9 +378,13 @@ my $g = $list_frame->Scrolled('TixGrid', -scrollbars => "se", -bd => 0, -floatingrows => 0, -floatingcols => 0, -leftmargin => 2, # selection and label -topmargin => 1, # top labels + -command => \&show_extended_info, # does not work, double click! -selectmode => "none", -selectunit => "row"); +# that does not work, I have no idea what has to be done +#$g->ItemStyle('window', -anchor => "c"); + $g->pack(qw/-expand 1 -fill both -padx 3 -pady 3/); $g->configure(-formatcmd=>[\&AlternatingLineColoring, $g]); $g->size(qw/col 4 -size 10char/); @@ -286,6 +395,11 @@ $g->size(qw/row default -size 1.1char -pad0 3/); setup_list(); update_grid(); +sub show_extended_info { + my ($x, $y) = @_; + print "double click on $x - $y\n"; +} + sub update_grid { # fill the header #$g->set(0,0, -itemtype => 'window', -widget => $g->Checkbutton()); @@ -313,18 +427,32 @@ sub update_grid { my (undef, $curlines) = $g->index(0, 'max'); for my $p (@schemes, @colls, @packs) { if (MatchesFilters($p)) { - if (!$g->infoExists(0,$i)) { - $g->set(0,$i, -itemtype => 'window', -widget => $g->Checkbutton); - } + # unset first so that the checkbutton is unmapped, otherwise crashes + $g->unset(0,$i) if $g->infoExists(0,$i); + $g->set(0,$i, -itemtype => 'window', + -widget => $Packages{$p}{'cb'}); + # $g->set(1,$i, -itemtype => 'text', -text => $Packages{$p}{'displayname'}); - $g->set(2,$i, -itemtype => 'text', -text => $Packages{$p}{'localrevision'}) - if defined($Packages{$p}{'localrevision'}); - $g->set(3,$i, -itemtype => 'text', -text => $Packages{$p}{'remoterevision'}) - if defined($Packages{$p}{'remoterevision'}); - $g->set(4,$i, -itemtype => 'text', -text => $Packages{$p}{'localcatalogueversion'}) - if defined($Packages{$p}{'localcatalogueversion'}); - $g->set(5,$i, -itemtype => 'text', -text => $Packages{$p}{'remotecatalogueversion'}) - if defined($Packages{$p}{'remotecatalogueversion'}); + if (defined($Packages{$p}{'localrevision'})) { + $g->set(2,$i, -itemtype => 'text', -text => $Packages{$p}{'localrevision'}); + } else { + $g->unset(2,$i); + } + if (defined($Packages{$p}{'remoterevision'})) { + $g->set(3,$i, -itemtype => 'text', -text => $Packages{$p}{'remoterevision'}) + } else { + $g->unset(3,$i); + } + if (defined($Packages{$p}{'localcatalogueversion'})) { + $g->set(4,$i, -itemtype => 'text', -text => $Packages{$p}{'localcatalogueversion'}) + } else { + $g->unset(4,$i); + } + if (defined($Packages{$p}{'remotecatalogueversion'})) { + $g->set(5,$i, -itemtype => 'text', -text => $Packages{$p}{'remotecatalogueversion'}) + } else { + $g->unset(5,$i); + } $g->set(6,$i, -itemtype => 'text', -text => $Packages{$p}{'shortdesc'}); $i++; } @@ -362,9 +490,37 @@ sub MatchesFilters { return 0; } # match - # TO BE DONE!!! + if (!$match_all) { + my $r = $match_entry->get; + # check for match on string + my $t = $Packages{$p}{'shortdesc'}; + $t |= ""; + my $lt = $Packages{$p}{'longdesc'}; + $lt |= ""; + if (($p =~ m/$r/) || ($t =~ m/$r/) || ($lt =~ m/$r/)) { + # do nothing, more checks have to be done + } else { + return 0; + } + } # selection - # TO BE DONE!!! + if ($selection_value == 0) { + # all -> maybe more checks + } elsif ($selection_value == 1) { + # only selected + if ($Packages{$p}{'selected'}) { + # do nothing, maybe more checks + } else { + # not selected package and only selected packages shown + return 0; + } + } else { + # only not selected + if ($Packages{$p}{'selected'}) { + # selected, but only not selected should be shown + return 0; + } # else do nothing + } # # if we come down to here the package matches return 1; @@ -389,7 +545,7 @@ sub AlternatingLineColoring { # format the checkbuttons backgrounds for my $i ($uly..$lry) { if ($w->infoExists(0,$i)) { - $cb = $w->entrycget(0, $i, "-window"); + my $cb = $w->entrycget(0, $i, "-window"); $cb->configure(-background => (($i-$uly)%2 ? 'gray70' : 'gray90')); } } @@ -422,34 +578,580 @@ $with_sel_frame->Radiobutton(-text => "applied", -variable => \$action_apply_filter, -value => 1)->pack(@left, @p_ii); $with_sel_frame->Radiobutton(-text => "not applied", -variable => \$action_apply_filter, -value => 0)->pack(@left, @p_ii); -$with_sel_frame->Button(-text => 'Install')->pack(@left, @p_ii); -$with_sel_frame->Button(-text => 'Upgrade')->pack(@left, @p_ii); -$with_sel_frame->Button(-text => 'Remove')->pack(@left, @p_ii); -$with_sel_frame->Button(-text => 'Backup')->pack(@left, @p_ii); +$with_sel_frame->Button(-text => 'Install', + -state => $::action_button_state, + -command => sub { install_selected_packages(); } + )->pack(@left, @p_ii); +$with_sel_frame->Button(-text => 'Upgrade', + -state => $::action_button_state, + -command => sub { update_selected_packages(); } + )->pack(@left, @p_ii); +$with_sel_frame->Button(-text => 'Remove', + -state => $::action_button_state, + -command => sub { remove_selected_packages(); } + )->pack(@left, @p_ii); +$with_sel_frame->Button(-text => 'Backup', + -state => $::action_button_state, + -command => sub { backup_selected_packages(); } + )->pack(@left, @p_ii); my $with_all_frame = $actions_frame->Labelframe(-text => "with all"); $with_all_frame->pack(@left, @p_ii); -$with_all_frame->Button(-text => 'Update all')->pack(@a_c,@left,@p_ii); +$with_all_frame->Button(-text => 'Update all', + -state => $::action_button_state, + -command => sub { update_all_packages(); } + )->pack(@a_c,@left,@p_ii); -######################## UNINSTALL ########################### -# uninstall screen -require("gui-uninstall.pl"); -# arch support not be done via tlmgr on win32 -if (!win32()) { - require("gui-arch.pl"); +######################## ARCH ########################### + +my @archsavail; +my @archsinstalled; +my %archs; +my $currentarch; + +sub init_archs { + if (!defined($tlmediatlpdb)) { + @archsavail = $localtlpdb->available_architectures; + } else { + @archsavail = $tlmediatlpdb->available_architectures; + } + $currentarch = $localtlmedia->platform(); + @archsinstalled = $localtlpdb->available_architectures; + foreach my $a (@archsavail) { + $archs{$a} = 0; + if (grep(/^$a$/,@archsinstalled)) { + $archs{$a} = 1; + } + } } -# config screen -require("gui-config.pl"); -if ($opt_load) { - run_update_functions(); + +sub do_arch_settings { + my $sw = $mw->Toplevel(-title => __("Select architectures to support")); + my %archsbuttons; + init_archs(); + $sw->transient($mw); + $sw->grab(); + my $subframe = $sw->Labelframe(-text => __("Select architectures to support")); + $subframe->pack(-fill => "both", -padx => "2m", -pady => "2m"); + foreach my $a (@archsavail) { + $archsbuttons{$a} = + $subframe->Checkbutton(-command => sub { check_on_removal($sw, $a); }, + -variable => \$archs{$a}, + -text => platform_desc($a) + )->pack(-anchor => 'w'); + } + my $arch_frame = $sw->Frame; + $arch_frame->pack(-padx => "10m", -pady => "5m"); + $arch_frame->Button(-text => __("Apply changes"), + -state => $::action_button_state, + -command => sub { apply_arch_changes(); $sw->destroy; })->pack(-side => 'left', -padx => "3m"); + $arch_frame->Button(-text => __("Cancel"), + -command => sub { $sw->destroy; })->pack(-side => 'left', -padx => "3m"); +} + +sub check_on_removal { + my $arch_frame = shift; + my $a = shift; + if (!$archs{$a} && $a eq $currentarch) { + # removal not supported + $archs{$a} = 1; + $arch_frame->Dialog(-title => "info", + -text => __("Removals of the main architecture not possible!"), + -buttons => [ __("Ok") ])->Show; + } +} + +sub apply_arch_changes { + my @todo_add; + my @todo_remove; + foreach my $a (@archsavail) { + if (!$archs{$a} && grep(/^$a$/,@archsinstalled)) { + push @todo_remove, $a; + next; + } + if ($archs{$a} && !grep(/^$a$/,@archsinstalled)) { + push @todo_add, $a; + next; + } + } + if (@todo_add) { + execute_action_gui ( "arch", "add", @todo_add ); + } + if (@todo_remove) { + execute_action_gui ( "arch", "remove", @todo_remove ); + } + if (@todo_add || @todo_remove) { + reinit_local_tlpdb(); + init_archs(); + } +} + +########## CONFIG ################### +# +my @fileassocdesc; +$fileassocdesc[0] = __("None"); +$fileassocdesc[1] = __("Only new"); +$fileassocdesc[2] = __("All"); +my %defaults; +my %changeddefaults; + +sub init_defaults_setting { + for my $key (keys %TeXLive::TLConfig::TLPDBOptions) { + if ($TeXLive::TLConfig::TLPDBOptions{$key}->[0] eq "b") { + $defaults{$key} = ($localtlpdb->option($key) ? 1 : 0); + } else { + $defaults{$key} = $localtlpdb->option($key); + } + } +} + +sub do_general_settings { + my $sw = $mw->Toplevel(-title => __("Default settings")); + $sw->transient($mw); + $sw->grab(); + init_defaults_setting(); + %changeddefaults = (); + for my $k (keys %defaults) { + $changeddefaults{$k}{'value'} = $defaults{$k}; + if ($TeXLive::TLConfig::TLPDBOptions{$k}->[0] eq "b") { + $changeddefaults{$k}{'display'} = ($defaults{$k} ? __("Yes") : __("No")); + } else { + if ($k eq "file_assocs") { + $changeddefaults{$k}{'display'} = $fileassocdesc[$defaults{$k}]; + } else { + $changeddefaults{$k}{'display'} = $defaults{$k}; + } + } + } + + my @config_set_l; + my @config_set_m; + my @config_set_r; + + my $back_config_set = $sw->Labelframe(-text => __("Default settings")); + my $back_config_buttons = $sw->Frame(); + $back_config_set->pack(-fill => "both", -padx => "2m", -pady => "2m"); + + push @config_set_l, + $back_config_set->Label(-text => __("Default package repository"), -anchor => "w"); + push @config_set_m, + $back_config_set->Label(-textvariable => \$changeddefaults{"location"}{'display'}); + push @config_set_r, + $back_config_set->Button(-text => __("Change"), + -command => sub { menu_default_location($sw); }); + + + push @config_set_l, + $back_config_set->Label(-text => __("Create formats on installation"), -anchor => "w"); + push @config_set_m, + $back_config_set->Label(-textvariable => \$changeddefaults{"create_formats"}{'display'}); + push @config_set_r, + $back_config_set->Button(-text => __("Toggle"), + -command => sub { toggle_setting("create_formats"); }); + + push @config_set_l, + $back_config_set->Label(-text => __("Install macro/font sources"), -anchor => "w"); + push @config_set_m, + $back_config_set->Label(-textvariable => \$changeddefaults{"install_srcfiles"}{'display'}); + push @config_set_r, + $back_config_set->Button(-text => __("Toggle"), + -command => sub { toggle_setting("install_srcfiles"); }); + + push @config_set_l, + $back_config_set->Label(-text => __("Install macro/font docs"), -anchor => "w"); + push @config_set_m, + $back_config_set->Label(-textvariable => \$changeddefaults{"install_docfiles"}{'display'}); + push @config_set_r, + $back_config_set->Button(-text => __("Toggle"), + -command => sub { toggle_setting("install_docfiles"); }); + + push @config_set_l, + $back_config_set->Label(-text => __("Default backup directory"), -anchor => "w"); + push @config_set_m, + $back_config_set->Label(-textvariable => \$changeddefaults{"backupdir"}{'display'}); + push @config_set_r, + $back_config_set->Button(-text => __("Change"), + -command => sub { + my $dir = $sw->chooseDirectory(); + if (defined($dir) && ($defaults{"backupdir"} ne $dir)) { + # see warning concerning UTF8 or other encoded dir names!! + $changeddefaults{"backupdir"}{'value'} = $dir; + $changeddefaults{"backupdir"}{'display'} = $dir; + } + }); + + push @config_set_l, + $back_config_set->Label(-text => __("Auto backup setting"), -anchor => "w"); + push @config_set_m, + $back_config_set->Label(-textvariable => \$changeddefaults{"autobackup"}{'display'}); + push @config_set_r, + $back_config_set->Button(-text => __("Change"), + -command => sub { select_autobackup($sw); }, -anchor => "w"); + + if (!win32()) { + push @config_set_l, + $back_config_set->Label(-text => __("Link destination for programs"), -anchor => "w"); + push @config_set_m, + $back_config_set->Label(-textvariable => \$changeddefaults{"sys_bin"}{'display'}); + push @config_set_r, + $back_config_set->Button(-text => __("Change"), + -command => sub { + my $dir = $sw->chooseDirectory(); + if (defined($dir) && ($defaults{"sys_bin"} ne $dir)) { + # see warning concerning UTF8 or other encoded dir names!! + $changeddefaults{"sys_bin"}{'value'} = $dir; + $changeddefaults{"sys_bin"}{'display'} = $dir; + } + }); + + push @config_set_l, + $back_config_set->Label(-text => __("Link destination for info docs"), -anchor => "w"); + push @config_set_m, + $back_config_set->Label(-textvariable => \$changeddefaults{"sys_info"}{'display'}); + push @config_set_r, + $back_config_set->Button(-text => __("Change"), + -command => sub { + my $dir = $sw->chooseDirectory(); + if (defined($dir) && ($defaults{"sys_info"} ne $dir)) { + # see warning concerning UTF8 or other encoded dir names!! + $changeddefaults{"sys_info"}{'value'} = $dir; + $changeddefaults{"sys_info"}{'display'} = $dir; + } + }); + + push @config_set_l, + $back_config_set->Label(-text => __("Link destination for man pages"), -anchor => "w"); + push @config_set_m, + $back_config_set->Label(-textvariable => \$changeddefaults{"sys_man"}{'display'}); + push @config_set_r, + $back_config_set->Button(-text => __("Change"), + -command => sub { + my $dir = $sw->chooseDirectory(); + if (defined($dir) && ($defaults{"sys_man"} ne $dir)) { + # see warning concerning UTF8 or other encoded dir names!! + $changeddefaults{"sys_man"}{'value'} = $dir; + $changeddefaults{"sys_man"}{'display'} = $dir; + } + }); + } + + if (win32()) { + push @config_set_l, + $back_config_set->Label(-text => __("Create shortcuts in menu and on desktop"), -anchor => "w"); + push @config_set_m, + $back_config_set->Label(-textvariable => \$changeddefaults{"desktop_integration"}{'display'}); + push @config_set_r, + $back_config_set->Button(-text => __("Toggle"), + -command => sub { toggle_setting("desktop_integration"); }); + + if (admin()) { + push @config_set_l, + $back_config_set->Label(-text => __("Install for all users"), -anchor => "w"); + push @config_set_m, + $back_config_set->Label(-textvariable => \$changeddefaults{"w32_multi_user"}{'display'}); + push @config_set_r, + $back_config_set->Button(-text => __("Toggle"), + -command => sub { toggle_setting("w32_multi_user"); }); + } + + push @config_set_l, + $back_config_set->Label(-text => __("Change file associations"), -anchor => "w"); + push @config_set_m, + $back_config_set->Label(-textvariable => \$changeddefaults{'file_assocs'}{'display'}); + push @config_set_r, + $back_config_set->Button(-text => __("Change"), + -command => sub { select_file_assocs($sw); }, -anchor => "w"); + + } + + for my $i (0..$#config_set_l) { + $config_set_l[$i]->grid( $config_set_m[$i], $config_set_r[$i], + -padx => "1m", -pady => "1m", -sticky => "nwe"); + } + + $back_config_buttons->pack(-padx => "10m", -pady => "5m"); + $back_config_buttons->Button(-text => __("Apply changes"), + -state => $::action_button_state, + -command => sub { apply_settings_changes(); $sw->destroy; })->pack(-side => 'left', -padx => "3m"); + $back_config_buttons->Button(-text => __("Cancel"), + -command => sub { $sw->destroy; })->pack(-side => 'left', -padx => "3m"); +} + +sub apply_settings_changes { + for my $k (keys %defaults) { + if ($defaults{$k} ne $changeddefaults{$k}{'value'}) { + $localtlpdb->option($k, $changeddefaults{$k}{'value'}); + } + } + $localtlpdb->save; +} + +######## PAPER ######### +my %papers; +my %currentpaper; +my %changedpaper; + +sub init_paper_xdvi { + if (!win32()) { + @{$papers{"xdvi"}} = TeXLive::TLPaper::get_paper_list("xdvi"); + $currentpaper{"xdvi"} = ${$papers{"xdvi"}}[0]; + } +} +sub init_paper_pdftex { + @{$papers{"pdftex"}} = TeXLive::TLPaper::get_paper_list("pdftex"); + $currentpaper{"pdftex"} = ${$papers{"pdftex"}}[0]; +} +sub init_paper_dvips { + @{$papers{"dvips"}} = TeXLive::TLPaper::get_paper_list("dvips"); + $currentpaper{"dvips"} = ${$papers{"dvips"}}[0]; +} +sub init_paper_dvipdfm { + @{$papers{"dvipdfm"}} = TeXLive::TLPaper::get_paper_list("dvipdfm"); + $currentpaper{"dvipdfm"} = ${$papers{"dvipdfm"}}[0]; +} +sub init_paper_context { + if (defined($localtlpdb->get_package("bin-context"))) { + @{$papers{"context"}} = TeXLive::TLPaper::get_paper_list("context"); + $currentpaper{"context"} = ${$papers{"context"}}[0]; + } +} +sub init_paper_dvipdfmx { + @{$papers{"dvipdfmx"}} = TeXLive::TLPaper::get_paper_list("dvipdfmx"); + $currentpaper{"dvipdfmx"} = ${$papers{"dvipdfmx"}}[0]; +} + +my %init_paper_subs; +$init_paper_subs{"xdvi"} = \&init_paper_xdvi; +$init_paper_subs{"pdftex"} = \&init_paper_pdftex; +$init_paper_subs{"dvips"} = \&init_paper_dvips; +$init_paper_subs{"context"} = \&init_paper_context; +$init_paper_subs{"dvipdfm"} = \&init_paper_dvipdfm; +$init_paper_subs{"dvipdfmx"} = \&init_paper_dvipdfmx; + +sub init_all_papers { + for my $p (keys %init_paper_subs) { + &{$init_paper_subs{$p}}(); + } +} + + +sub do_paper_settings { + init_all_papers(); + my $sw = $mw->Toplevel(-title => __("Paper settings")); + $sw->transient($mw); + $sw->grab(); + + %changedpaper = %currentpaper; + + my $lower = $sw->Frame; + $lower->pack(-fill => "both"); + + my $back_config_pap = $lower->Labelframe(-text => __("Paper settings")); + my $back_config_buttons = $sw->Frame(); + + + my $back_config_pap_l1 = $back_config_pap->Label(-text => __("Default paper for all"), -anchor => "w"); + my $back_config_pap_m1 = $back_config_pap->Button(-text => "A4", + -command => sub { change_paper("all", "a4"); }); + my $back_config_pap_r1 = $back_config_pap->Button(-text => "letter", + -command => sub { change_paper("all", "letter"); }); + + $back_config_pap_l1->grid( $back_config_pap_m1, $back_config_pap_r1, + -padx => "2m", -pady => "2m", -sticky => "nswe"); + + my (%l,%m,%r); + foreach my $p (sort keys %papers) { + if (($p eq "context") && !defined($localtlpdb->get_package("bin-context"))) { + next; + } + $l{$p} = $back_config_pap->Label(-text => __("Default paper for") . " $p", -anchor => "w"); + $m{$p} = $back_config_pap->Label(-textvariable => \$changedpaper{$p}, -anchor => "w"); + $r{$p} = $back_config_pap->Button(-text => __("Change"), + -command => sub { select_paper($sw,$p); }, -anchor => "w"); + $l{$p}->grid( $m{$p}, $r{$p}, + -padx => "2m", -pady => "2m", -sticky => "nsw"); +} + + $back_config_pap->pack(-side => 'left', -fill => "both", -padx => "2m", -pady => "2m"); + + $back_config_buttons->pack(-padx => "10m", -pady => "5m"); + $back_config_buttons->Button(-text => __("Apply changes"), + -state => $::action_button_state, + -command => sub { apply_paper_changes(); $sw->destroy; })->pack(-side => 'left', -padx => "3m"); + $back_config_buttons->Button(-text => __("Cancel"), + -command => sub { $sw->destroy; })->pack(-side => 'left', -padx => "3m"); +} + + +sub menu_default_location { + my $mw = shift; + my $val; + my $sw = $mw->Toplevel(-title => __("Change default package repository")); + $sw->transient($mw); + $sw->grab(); + $sw->Label(-text => __("New default package repository"))->pack(-padx => "2m", -pady => "2m"); + + my $f1 = $sw->Frame; + my $entry = $f1->Entry(-text => $val, -width => 50); + $entry->pack(-side => "left",-padx => "2m", -pady => "2m"); + + my $f2 = $sw->Frame; + $f2->Button(-text => __("Choose Directory"), + -command => sub { + my $var = $sw->chooseDirectory; + if (defined($var)) { + $entry->delete(0,"end"); + $entry->insert(0,$var); + } + })->pack(-side => "left",-padx => "2m", -pady => "2m"); + $f2->Button(-text => __("Default net package repository"), + -command => sub { + $entry->delete(0,"end"); + $entry->insert(0,$TeXLiveURL); + })->pack(-side => "left",-padx => "2m", -pady => "2m"); + $f1->pack; + $f2->pack; + + my $f = $sw->Frame; + my $okbutton = $f->Button(-text => __("Ok"), + -command => sub { $changeddefaults{'location'}{'value'} = + $changeddefaults{'location'}{'display'} = + $entry->get; + $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'); + $sw->bind('', [ $okbutton, 'Invoke' ]); + $sw->bind('', [ $cancelbutton, 'Invoke' ]); +} + +sub toggle_setting() { + my ($key) = @_; + my $old = $changeddefaults{$key}{'value'}; + my $new = ($old ? 0 : 1); + $changeddefaults{$key}{'display'} = ($new ? __("Yes") : __("No")); + $changeddefaults{$key}{'value'} = $new; +} + + +sub apply_paper_changes { + $mw->Busy(-recurse => 1); + for my $k (keys %changedpaper) { + if ($currentpaper{$k} ne $changedpaper{$k}) { + execute_action_gui ( "paper", $k, "paper", $changedpaper{$k}); + &{$init_paper_subs{$k}}(); + } + } + $mw->Unbusy; +} + +sub change_paper { + my ($prog, $pap) = @_; + if ($prog eq "all") { + for my $k (keys %changedpaper) { + $changedpaper{$k} = $pap; + } + } else { + $changedpaper{$prog} = $pap; + } +} + +sub select_paper { + my $back_config = shift; + my $prog = shift; + my $foo = $back_config->Toplevel(-title => __("Select paper format for") . " $prog"); + $foo->transient($back_config); + $foo->grab(); + my $var = $changedpaper{$prog}; + my $opt = $foo->BrowseEntry(-label => __("Default paper for") . " $prog", -variable => \$var); + foreach my $p (sort @{$papers{$prog}}) { + $opt->insert("end",$p); + } + $opt->pack(-padx => "2m", -pady => "2m"); + my $f = $foo->Frame; + my $okbutton = $f->Button(-text => __("Ok"), -command => sub { change_paper($prog,$var); $foo->destroy; })->pack(-side => "left", -padx => "2m", -pady => "2m"); + my $cancelbutton = $f->Button(-text => __("Cancel"), -command => sub { $foo->destroy; })->pack(-side => "left", -padx => "2m", -pady => "2m"); + $f->pack; + $foo->bind('', [ $okbutton, 'Invoke' ]); + $foo->bind('', [ $cancelbutton, 'Invoke' ]); } +sub select_autobackup { + my $mw = shift; + my $foo = $mw->Toplevel(-title => __("Auto backup setting")); + $foo->transient($mw); + $foo->grab(); + my $var = $defaults{"autobackup"}; + my $opt = $foo->BrowseEntry(-label => __("Auto backup setting"), + -variable => \$var); + my @al; + push @al, "-1 (" . __("keep arbitrarily many") . ")"; + push @al, "0 (" . __("disable") . ")"; + for my $i (1..100) { + push @al, $i; + } + foreach my $p (@al) { + $opt->insert("end",$p); + } + $opt->pack(-padx => "2m", -pady => "2m"); + my $f = $foo->Frame; + my $okbutton = $f->Button(-text => __("Ok"), + -command => sub { + $var =~ s/ .*$//; + $changeddefaults{"autobackup"}{'value'} = $var; + $changeddefaults{"autobackup"}{'display'} = $var; + $foo->destroy; + } + )->pack(-side => "left", -padx => "2m", -pady => "2m"); + my $cancelbutton = $f->Button(-text => __("Cancel"), -command => sub { $foo->destroy; })->pack(-side => "left", -padx => "2m", -pady => "2m"); + $f->pack; + $foo->bind('', [ $okbutton, 'Invoke' ]); + $foo->bind('', [ $cancelbutton, 'Invoke' ]); +} -if (defined($opt_screen)) { - $back->raise("$opt_screen"); + +sub select_file_assocs { + my $sw = shift; + my $foo = $sw->Toplevel(-title => __("Change file associations")); + $foo->transient($mw); + $foo->grab(); + my $var = $defaults{"file_assocs"}; + my $opt = $foo->BrowseEntry(-label => __("Change file associations"), + -variable => \$var); + my @al; + for my $i (0..2) { + push @al, "$i $fileassocdesc[$i]"; + } + foreach my $p (@al) { + $opt->insert("end",$p); + } + $opt->pack(-padx => "2m", -pady => "2m"); + my $f = $foo->Frame; + my $okbutton = $f->Button(-text => __("Ok"), + -command => sub { + $var = substr($var,0,1); + $changeddefaults{"file_assocs"}{'display'} = $fileassocdesc[$var]; + $changeddefaults{"file_assocs"}{'value'} = $var; + + $foo->destroy; + } + )->pack(-side => "left", -padx => "2m", -pady => "2m"); + my $cancelbutton = $f->Button(-text => __("Cancel"), -command => sub { $foo->destroy; })->pack(-side => "left", -padx => "2m", -pady => "2m"); + $f->pack; + $foo->bind('', [ $okbutton, 'Invoke' ]); + $foo->bind('', [ $cancelbutton, 'Invoke' ]); } + + +################ END FUNCTIONS + +if ($opts{"load"}) { + run_update_functions(); +} + + info(__("Completed") . "\n"); $mw->deiconify; @@ -478,10 +1180,14 @@ sub init_install_media { $mw->Dialog(-title => "warning", -text => __("Could not load the TeX Live Database from %s\nIf you want to install or update packages, please try with a different package repository!\n\nFor configuration and removal you don\'t have to do anything.", $newroot), -buttons => [ __("Ok") ])->Show; - $location = __("...please change me..."); + $tlmediatlpdb = undef; + $tlmediasrc = undef; + update_list_remote(); + update_grid(); + update_loaded_location_string("none"); } else { $tlmediatlpdb = $tlmediasrc->tlpdb; - setup_list(); + update_list_remote(); update_grid(); } } @@ -495,9 +1201,10 @@ sub set_text_win { } sub install_selected_packages { - if (@_) { + my @foo = SelectedPackages(); + if (@foo) { my @args = qw/install/; - push @args, @_; + push @args, @foo; execute_action_gui(@args); reinit_local_tlpdb(); # now we check that the installation has succeeded by checking that @@ -513,22 +1220,51 @@ sub install_selected_packages { } } +sub SelectedPackages { + my @ret; + # first select those that are + for my $p (keys %Packages) { + next if !$Packages{$p}{'selected'}; + if ($action_apply_filter) { + if (MatchesFilters($p)) { + push @ret, $p; + } + } else { + push @ret, $p; + } + } + return @ret; +} + +sub update_all_packages { + my @args = qw/update/; + if ($critical_updates_present) { + $opts{"self"} = 1; + } else { + $opts{"all"} = 1; + } + execute_action_gui(qw/update/); + if ($critical_updates_present) { + # terminate here immediately so that we are sure the auto-updater + # is run immediately + # make sure we exit in finish(0) + $::gui_mode = 0; + finish(0); + } + reinit_local_tlpdb(); +} + sub update_selected_packages { - if (@_) { + my @foo = SelectedPackages(); + if (@foo) { my @args = qw/update/; # argument processing # in case we have critical updates present we do put the list of # critical updates into the argument instead of --all if ($critical_updates_present) { $opts{"self"} = 1; - } else { - if ($_[0] eq "--all") { - $opts{"all"} = 1; - # shift away the --all - shift; - } } - push @args, @_; + push @args, @foo; execute_action_gui(@args); if ($critical_updates_present) { # terminate here immediately so that we are sure the auto-updater @@ -542,9 +1278,10 @@ sub update_selected_packages { } sub remove_selected_packages { - if (@_) { + my @foo = SelectedPackages(); + if (@foo) { my @args = qw/remove/; - push @args, @_; + push @args, @foo; execute_action_gui(@args); reinit_local_tlpdb(); my $do_warn = 0; @@ -558,6 +1295,15 @@ sub remove_selected_packages { } } +sub backup_selected_packages { + my @foo = SelectedPackages(); + if (@foo) { + my @args = qw/backup/; + push @args, @foo; + execute_action_gui(@args); + } +} + sub reinit_local_tlpdb { $mw->Busy(-recurse => 1); $localtlpdb = TeXLive::TLPDB->new ("root" => "$Master"); @@ -567,13 +1313,11 @@ sub reinit_local_tlpdb { $mw->Unbusy; } - # # creates/updates the list of packages as shown in tix grid # sub setup_list { my @do_later; - my @do_later_media; for my $p ($localtlpdb->list_packages()) { # collect packages containing a . for later # we want to ignore them in most cases but those where there is @@ -587,7 +1331,10 @@ sub setup_list { $Packages{$p}{'displayname'} = $p; $Packages{$p}{'localrevision'} = $tlp->revision; $Packages{$p}{'shortdesc'} = $tlp->shortdesc; + $Packages{$p}{'longdesc' } = $tlp->longdesc; $Packages{$p}{'installed'} = 1; + $Packages{$p}{'selected'} = 0; + $Packages{$p}{'cb'} = $g->Checkbutton(-variable => \$Packages{$p}{'selected'}); if (($tlp->category eq "Collection") || ($tlp->category eq "Scheme")) { $Packages{$p}{'category'} = $tlp->category; @@ -598,17 +1345,19 @@ sub setup_list { $Packages{$p}{'localcatalogueversion'} = $tlp->cataloguedata->{'version'}; } } - if (defined($tlmediatlpdb)) { - for my $p ($tlmediatlpdb->list_packages()) { - if ($p =~ m;\.;) { - push @do_later_media, $p; - next; - } - my $tlp = $tlmediatlpdb->get_package($p); + for my $p (@do_later) { + my $s = $p; + $s =~ s!\.[^.]*$!!; + if (!defined($Packages{$s})) { + my $tlp = $localtlpdb->get_package($p); + # collect information about that package we will show $Packages{$p}{'displayname'} = $p; - $Packages{$p}{'remoterevision'} = $tlp->revision; - # overwrite, we assume that the remove version is better ;-) + $Packages{$p}{'localrevision'} = $tlp->revision; $Packages{$p}{'shortdesc'} = $tlp->shortdesc; + $Packages{$p}{'longdesc' } = $tlp->longdesc; + $Packages{$p}{'installed'} = 1; + $Packages{$p}{'selected'} = 0; + $Packages{$p}{'cb'} = $g->Checkbutton(-variable => \$Packages{$p}{'selected'}); if (($tlp->category eq "Collection") || ($tlp->category eq "Scheme")) { $Packages{$p}{'category'} = $tlp->category; @@ -616,21 +1365,41 @@ sub setup_list { $Packages{$p}{'category'} = "Other"; } if (defined($tlp->cataloguedata->{'version'})) { - $Packages{$p}{'remotecatalogueversion'} = $tlp->cataloguedata->{'version'}; + $Packages{$p}{'localcatalogueversion'} = $tlp->cataloguedata->{'version'}; } } } - # - for my $p (@do_later) { - my $s = $p; - $s =~ s!\.[^.]*$!!; - if (!defined($Packages{$s})) { - my $tlp = $localtlpdb->get_package($p); - # collect information about that package we will show + update_list_remote(); +} + +sub update_list_remote { + my @do_later_media; + print "TODO move the check from critical_updates_present from the old sub create_update_list here!!!"; + # clear old info from remote media + for my $p (keys %Packages) { + if (!$Packages{$p}{'installed'}) { + delete $Packages{$p}; + next; + } + delete $Packages{$p}{'remoterevision'}; + delete $Packages{$p}{'remotecatalogueversion'}; + } + if (defined($tlmediatlpdb)) { + for my $p ($tlmediatlpdb->list_packages()) { + if ($p =~ m;\.;) { + push @do_later_media, $p; + next; + } + my $tlp = $tlmediatlpdb->get_package($p); $Packages{$p}{'displayname'} = $p; - $Packages{$p}{'localrevision'} = $tlp->revision; + $Packages{$p}{'remoterevision'} = $tlp->revision; + # overwrite, we assume that the remove version is better ;-) $Packages{$p}{'shortdesc'} = $tlp->shortdesc; - $Packages{$p}{'installed'} = 1; + $Packages{$p}{'longdesc' } = $tlp->longdesc; + $Packages{$p}{'selected'} = 0 + unless defined $Packages{$p}{'selected'}; + $Packages{$p}{'cb'} = $g->Checkbutton(-variable => \$Packages{$p}{'selected'}) + unless defined $Packages{$p}{'cb'}; if (($tlp->category eq "Collection") || ($tlp->category eq "Scheme")) { $Packages{$p}{'category'} = $tlp->category; @@ -638,7 +1407,7 @@ sub setup_list { $Packages{$p}{'category'} = "Other"; } if (defined($tlp->cataloguedata->{'version'})) { - $Packages{$p}{'localcatalogueversion'} = $tlp->cataloguedata->{'version'}; + $Packages{$p}{'remotecatalogueversion'} = $tlp->cataloguedata->{'version'}; } } } @@ -651,6 +1420,11 @@ sub setup_list { $Packages{$p}{'displayname'} = $p; $Packages{$p}{'remoterevision'} = $tlp->revision; $Packages{$p}{'shortdesc'} = $tlp->shortdesc; + $Packages{$p}{'longdesc' } = $tlp->longdesc; + $Packages{$p}{'selected'} = 0 + unless defined $Packages{$p}{'selected'}; + $Packages{$p}{'cb'} = $g->Checkbutton(-variable => \$Packages{$p}{'selected'}) + unless defined $Packages{$p}{'cb'}; if (($tlp->category eq "Collection") || ($tlp->category eq "Scheme")) { $Packages{$p}{'category'} = $tlp->category; @@ -674,10 +1448,10 @@ sub setup_list { sub menu_edit_location { my $key = shift; my $val; - my $sw = $mw->Toplevel(-title => __("Change package repository")); + my $sw = $mw->Toplevel(-title => __("Load package repository")); $sw->transient($mw); $sw->grab(); - $sw->Label(-text => __("New package repository:"))->pack(@p_ii); + $sw->Label(-text => __("Package repository:"))->pack(@p_ii); my $entry = $sw->Entry(-text => $location, -width => 30); $entry->pack(); my $f1 = $sw->Frame; @@ -698,8 +1472,9 @@ sub menu_edit_location { my $f = $sw->Frame; my $okbutton = $f->Button(-text => __("Ok"), -command => sub { $location = $entry->get; - run_update_functions(); $sw->destroy; + update_loaded_location_string(); + run_update_functions(); })->pack(@left, @p_ii); my $cancelbutton = $f->Button(-text => __("Cancel"), -command => sub { $sw->destroy })->pack(@right, @p_ii); @@ -708,6 +1483,12 @@ sub menu_edit_location { $sw->bind('', [ $cancelbutton, 'Invoke' ]); } +sub update_loaded_location_string { + my $arg = shift; + $arg || ($arg = $location); + $menu->entryconfigure('end', -label => "Loaded repository: $arg"); +} + sub run_update_functions { foreach my $f (@update_function_list) { &{$f}(); @@ -723,20 +1504,11 @@ sub check_location_on_ctan { } sub execute_action_gui { - # my $td = $mw->Toplevel(-title => __("Status Window")); - # $td->transient($mw); - # $td->grab(); - # my $ok = $td->Button(-text => __("Ok"), @p_iii, - # -command => sub { $td->destroy; }); - # my $lab = $td->Label(-text => __("Starting") . " @_\n"); - # $lab->pack; $mw->Busy(-recurse => 1); + info ("Executing action @_\n"); execute_action(@_); info(__("Completed") . "\n"); $mw->Unbusy; - # my $labb = $td->Label(-text => __("Completed")); - # $labb->pack; - # $ok->pack; } sub give_warning_window { -- cgit v1.2.3