summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThierry Vignaud <tv@mageia.org>2013-03-16 09:03:22 +0000
committerThierry Vignaud <tv@mageia.org>2013-03-16 09:03:22 +0000
commit40392ce42b6eee10c34eb0d8d1cfef77c8a7962c (patch)
treef69e79c61ee7ade855e147bd5be7ca0023d10fa1
parenta502e85fbd3a6900e95954ca09b04ed8fc5cbe8d (diff)
downloadurpmi-40392ce42b6eee10c34eb0d8d1cfef77c8a7962c.tar
urpmi-40392ce42b6eee10c34eb0d8d1cfef77c8a7962c.tar.gz
urpmi-40392ce42b6eee10c34eb0d8d1cfef77c8a7962c.tar.bz2
urpmi-40392ce42b6eee10c34eb0d8d1cfef77c8a7962c.tar.xz
urpmi-40392ce42b6eee10c34eb0d8d1cfef77c8a7962c.zip
new widget to share with rpmdrake for global progress bar (mga#778)
-rw-r--r--MANIFEST1
-rw-r--r--NEWS1
-rw-r--r--gurpm/RPMProgressDialog.pm280
-rwxr-xr-xgurpmi2168
4 files changed, 313 insertions, 137 deletions
diff --git a/MANIFEST b/MANIFEST
index e4d566f9..542a09b3 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -1,6 +1,7 @@
gurpmi
gurpmi.desktop.in
gurpmi.pm
+gurpm/RPMProgressDialog.pm
gurpmi2
inst.list
Makefile.PL
diff --git a/NEWS b/NEWS
index 00f388b3..eb02dbac 100644
--- a/NEWS
+++ b/NEWS
@@ -6,6 +6,7 @@
there're no update media (#1024)' as it break looking for deps in other media
with --update (mga#2317)
- gurpmi:
+ o split global progress bar widget for rpmdrake (mga#778)
o support exceptions in callback in main wrapper too
o support other distros which do not handle exceptions in gtk+ callbacks
o use new exception management
diff --git a/gurpm/RPMProgressDialog.pm b/gurpm/RPMProgressDialog.pm
new file mode 100644
index 00000000..13d79c42
--- /dev/null
+++ b/gurpm/RPMProgressDialog.pm
@@ -0,0 +1,280 @@
+package gurpm::RPMProgressDialog;
+
+#- Copyright (C) 2005 MandrakeSoft SA
+#- Copyright (C) 2005-2010 Mandriva SA
+#- Copyright (C) 2013 Mageia
+
+# Sharing code from gurpmi2 && Rpmdrake::gurpm
+# Gtk2 only (no ugtk2/mygtk2) as it's used by gurpmi too...
+#
+
+=head1 SYNOPSYS
+
+gurpm::RPMProgressDialog is a widget for gurpmi, rpmdrake (drakx already has its own)
+that presents a global progress bar.
+
+=head1 USAGE
+
+How to use:
+
+ my $w = gurpm::RPMProgressDialog->new:
+ #$w->change_widget(Gtk2::Box->new);
+ label(N("Preparing packages installation..."));
+ ... # compute packages to install/remove...
+ $w->init_progressbar;
+ urpm::main_loop::run($urpm, $state, $nb, \@ask_unselect, {
+ trans_log => &gurpm::RPMProgressDialog::callback_download,
+ inst => \&gurpm::RPMProgressDialog::callback_inst,
+ trans => \&gurpm::RPMProgressDialog::callback_inst,
+ callback_report_uninst => ...
+ ....
+
+=head1 DESCRIPTION
+
+=cut
+
+use strict;
+use Gtk2;
+use urpm::download;
+use urpm::msg 'N';
+use urpm::util qw(max member);
+
+our @ISA = qw(Gtk2::Window);
+
+sub title {
+ $::auto_select ? N("Distribution Upgrade") : N("Packages installation");
+}
+
+# package variable needed in order to simplify callbacks
+my $mainw;
+
+my $progressbar_size = 450;
+my ($progress_nb, $download_nb);
+
+
+=head2 Creators
+
+=over 4
+
+=item gurpm::RPMProgressDialog->new($urpm, $o_quit)
+
+Creates a new Progress Dialog.
+
+Arguments are an urpm object and a quit routine reference.
+
+=cut
+
+
+sub new {
+ my ($self, $urpm, $o_quit) = @_;
+ # my $w = ugtk2->new($title, %options, default_width => 600, width => 600);
+ my $w = $mainw = bless(Gtk2::Window->new('toplevel'), $self);
+ $::main_window = $w;
+ $w->set_border_width(12);
+ $w->set_title($w->title);
+ $w->signal_connect(destroy => $o_quit) if $o_quit;
+ $w->set_position('center');
+ $w->set_default_size($progressbar_size, 60);
+ $w->set_type_hint('dialog'); # for matchbox window manager during install
+ $w->set_modal(1); # for matchbox window manager during install
+ $w->{mainbox} = Gtk2::VBox->new(0, 5);
+ $w->add($w->{mainbox});
+ $w->{urpm} = $urpm;
+ bless($w, $self);
+}
+
+=back
+
+=head2 Methods
+
+=over 4
+
+=item change_widget($w, $box_widget)
+
+Replaces the contents of the main window with the specified box
+(avoids popup multiplication)
+
+=cut
+
+sub change_widget {
+ my ($w, $mainbox) = @_;
+ $w->remove($w->{mainbox});
+ $w->add($w->{mainbox} = $mainbox);
+ $w->show_all;
+}
+
+=item label($w, $o_text)
+
+sets the window to a please-wait message
+
+=cut
+
+sub label {
+ my ($w, $o_text) = @_;
+ my $wait_vbox = Gtk2::VBox->new(0, 5);
+ my $label = Gtk2::Label->new($o_text || N("Please wait..."));
+ $label->set_alignment(0.5, 0.5);
+ $wait_vbox->pack_start($label, 1, 1, 0);
+ $w->change_widget($wait_vbox);
+ $w->sync;
+}
+
+
+# From ugtk2.pm/mygtk2.pm:
+sub gtk_new_Label_Left {
+ my ($text) = @_;
+ my $w = Gtk2::Label->new($text);
+ $w->set_alignment(0, 0);
+ $w;
+}
+
+=item init_progressbar($w)
+
+Put a progress bar in the dialog.
+
+=cut
+
+sub init_progressbar {
+ my ($w) = @_;
+ my $vbox = Gtk2::VBox->new(0, 5);
+
+ my $global_label = gtk_new_Label_Left('<b>' . $w->title . '</b>');
+ $global_label->set_use_markup(1);
+ $vbox->pack_start($global_label, 0, 0, 0);
+
+ my $global_progressbar = $w->{global_progressbar} = Gtk2::ProgressBar->new;
+ $vbox->pack_start($global_progressbar, 0, 0, 0);
+
+ $vbox->pack_start($w->{progresslabel} = gtk_new_Label_Left('-'), 1, 1, 0);
+
+ my $progressbar = Gtk2::ProgressBar->new;
+ $progressbar->set_size_request($progressbar_size, -1);
+ $vbox->pack_start($progressbar, 0, 0, 0);
+ $w->{progressbar} = $progressbar;
+
+ $w->change_widget($vbox);
+}
+
+=item set_progresslabel($w, $text)
+
+Update the progress label
+
+=cut
+
+sub set_progresslabel {
+ my ($w, $text) = @_;
+ $w->{progresslabel}->set_label($text);
+}
+
+=item set_progressbar($w, $local_ratio)
+
+Update the progress bar
+
+=cut
+
+sub set_progressbar {
+ my ($w, $local_ratio) = @_;
+ if ($progress_nb || $download_nb) { # this happens when computing transaction
+ $w->{global_progressbar}->set_fraction(($download_nb + $progress_nb - 1 + $local_ratio) / 2 / $w->{urpm}{nb_install});
+ }
+ $w->{progressbar}->set_fraction($local_ratio);
+}
+
+=item sync($w)
+
+tell Gtk+ to refresh the dialog content if needed.
+
+=cut
+
+sub sync {
+ my ($w) = @_;
+ $w->show;
+ Gtk2->main_iteration while Gtk2->events_pending;
+}
+
+=back
+
+=head2 Callbacks
+
+=over 4
+
+=item callback_inst($urpm, $type, $id, $subtype, $amount, $total)
+
+This callback is called when a new RPM DB transaction is created and
+when packages are installed.
+
+Its purpose is to display installation progress in the dialog.
+
+=cut
+
+sub callback_inst {
+ my ($urpm, $type, $id, $subtype, $amount, $total) = @_;
+ my $pkg = defined $id ? $urpm->{depslist}[$id] : undef;
+ if ($subtype eq 'start') {
+ if ($type eq 'trans') {
+ $mainw->set_progresslabel(N("Preparing..."));
+ } elsif ($pkg) {
+ $progress_nb++;
+ $download_nb = max($download_nb, $progress_nb);
+ $mainw->set_progressbar(0);
+ $mainw->set_progresslabel(
+ N("Installing package `%s' (%s/%s)...", $pkg->name, $progress_nb, $urpm->{nb_install})
+ );
+ }
+ } elsif ($subtype eq 'progress') {
+ $mainw->set_progressbar($amount / $total);
+ }
+ $mainw->sync;
+}
+
+sub callback_remove {
+ $mainw->set_progresslabel(N("removing %s", $_[0]));
+}
+
+=item callback_download($mode, $file, $percent, $total, $eta, $speed)
+
+This callback is called when packages are downloaded prior being installed
+in a RPM transaction.
+
+Its purpose is to display download progress in the dialog.
+
+=cut
+
+sub callback_download {
+ my ($mode, $file, $percent, $total, $eta, $speed) = @_;
+
+ urpm::download::sync_logger($mode, $file, $percent, $total, $eta, $speed);
+
+ if (member($mode, 'start', 'progress')) {
+ $file =~ s|/*\s*$||; $file =~ s|.*/||;
+ $mainw->set_progresslabel(N("Downloading package `%s'...", $file) . "\n" .
+ &urpm::download::progress_text($mode, $percent, $total, $eta, $speed));
+ }
+ if ($mode eq 'start') {
+ $download_nb++;
+ $mainw->set_progressbar(0);
+ select(undef, undef, undef, 0.1); #- hackish
+ } elsif ($mode eq 'progress') {
+ $mainw->set_progressbar($percent / 100);
+ } elsif ($mode eq 'end') {
+ $mainw->set_progressbar(1);
+ } elsif ($mode eq 'error') {
+ #- error is 3rd argument, saved in $percent
+ push @{$mainw->{urpm}{download_errors}}, N("...retrieving failed: %s", $percent);
+ }
+ $mainw->sync;
+}
+
+=back
+
+=head1 Copyright
+
+Copyright (C) 2005 MandrakeSoft SA
+
+Copyright (C) 2005-2010 Mandriva SA
+
+Copyright (C) 2011-2013 Mageia
+
+=cut
+
+1;
diff --git a/gurpmi2 b/gurpmi2
index d1d3be26..d652c8e8 100755
--- a/gurpmi2
+++ b/gurpmi2
@@ -11,7 +11,7 @@ BEGIN { #- set up a safe path and environment
}
use gurpmi;
-use urpm::download;
+use gurpm::RPMProgressDialog;
use urpm::install;
use urpm::media;
use urpm::signature;
@@ -29,8 +29,6 @@ our $force = 0;
our $test = 0;
our $use_provides = 1;
-my $progressbar_size = 450;
-
# For other distros w/o exception support:
eval { Glib->enable_exceptions2 };
if (my $err = $@) {
@@ -38,32 +36,7 @@ if (my $err = $@) {
}
#- GUI globals
-my ($mainw, $mainbox);
-
-#- Replaces the contents of the main window with the specified box
-#- (avoids popup multiplication)
-sub change_mainw {
- $mainw->remove($mainbox);
- ($mainbox) = @_;
- $mainw->add($mainbox);
- $mainw->show_all;
-}
-
-sub sync () {
- $mainw->show;
- Gtk2->main_iteration while Gtk2->events_pending;
-}
-
-#- sets the window to a please-wait message
-sub wait_label {
- my ($o_text) = @_;
- my $wait_vbox = Gtk2::VBox->new(0, 5);
- my $wait_label = Gtk2::Label->new($o_text || N("Please wait..."));
- $wait_label->set_alignment(0.5, 0.5);
- $wait_vbox->pack_start($wait_label, 1, 1, 0);
- change_mainw($wait_vbox);
- sync();
-}
+my $mainw;
my @all_rpms = gurpmi::parse_command_line();
@@ -73,25 +46,22 @@ $> and fatal(N("Must be root"));
Gtk2->init;
-my $title = $::auto_select ? N("Distribution Upgrade") : N("Packages installation");
+#- Initialize urpm
+
+my $urpm;
+{
+ local @ARGV = @ARGV;
+ $urpm = urpm->new_parse_cmdline;
+}
#- Create main window
-$mainw = Gtk2::Window->new('toplevel');
-$::main_window = $mainw;
-$mainw->set_border_width(12);
-$mainw->set_title($title);
-$mainw->signal_connect(destroy => \&quit);
-$mainw->set_position('center');
-$mainw->set_default_size($progressbar_size, 60);
-$mainw->set_type_hint('dialog'); # for matchbox window manager during install
-$mainw->set_modal(1); # for matchbox window manager during install
-$mainbox = Gtk2::VBox->new(0, 5);
-$mainw->add($mainbox);
+$mainw = gurpm::RPMProgressDialog->new($urpm, \&quit);
#- Performs installation
-my $urpm = configure_urpm();
+configure_urpm($urpm);
+
my $state = {};
my %requested = $urpm->register_rpms(@all_rpms);
if (@gurpmi::names) {
@@ -100,7 +70,7 @@ if (@gurpmi::names) {
) || $force or exit 1;
}
-wait_label(N("Preparing packages installation..."));
+$mainw->label(N("Preparing packages installation..."));
#- return value is true if program should be restarted (in order to take care of important
#- packages being upgraded (problably urpmi and perl-URPM, but maybe rpm too, and glibc also ?).
@@ -134,12 +104,8 @@ Gtk2->main;
my ($rpm_lock, $urpmi_lock);
#- Creates and configure an urpm object for this application to use.
-sub configure_urpm() {
- my $urpm;
- {
- local @ARGV = @ARGV;
- $urpm = urpm->new_parse_cmdline;
- }
+sub configure_urpm {
+ my ($urpm) = @_;
$urpm->{fatal} = sub {
printf STDERR "%s\n", $_[1];
@@ -184,7 +150,6 @@ sub configure_urpm() {
update => $::update,
);
$urpm->{options}{'verify-rpm'} = 0 if $gurpmi::options{'no-verify-rpm'};
- $urpm;
}
#- Callback for choices
@@ -230,7 +195,7 @@ sub ask_continue {
$quit_button->signal_connect(clicked => sub { $urpm->{log}("=> cancel"); &quit(); exit 1 });
$continue_button->signal_connect(clicked => sub { $urpm->{log}("=> ok"); goto &$nextclosure });
add_button_box($vbox, $quit_button, $continue_button);
- change_mainw($vbox);
+ $mainw->change_widget($vbox);
# default is to continue, but according to some HIG, warning should reverse the choise and defaults to abort
$mainw->set_focus($continue_button); # also set_default should be called but it gives a warning!
}
@@ -257,7 +222,7 @@ sub ask_continue_blocking {
}
sub do_install {
- wait_label();
+ $mainw->label;
my @ask_remove = urpm::select::removed_packages($state);
@ask_remove
? ask_continue_if_no_auto(N(
@@ -289,54 +254,11 @@ sub do_install_2 () {
}
sub do_install_3 () {
- wait_label($title);
+ $mainw->label($mainw->title);
my ($local_sources, $blists) = urpm::get_pkgs::selected2local_and_blists($urpm, $state->{selected});
$local_sources || $blists or $urpm->{fatal}(3, N("unable to get source packages, aborting"));
- my $vbox = Gtk2::VBox->new(0, 5);
- my $global_label = gtk_new_Label_Left("<b>$title</b>");
- $global_label->set_use_markup(1);
- $vbox->pack_start($global_label, 0, 0, 0);
-
- my $global_progressbar = Gtk2::ProgressBar->new;
- $vbox->pack_start($global_progressbar, 0, 0, 0);
-
- my $progress_label = gtk_new_Label_Left('-');
- $vbox->pack_start($progress_label, 1, 1, 0);
-
-
- my $progressbar = Gtk2::ProgressBar->new;
- $progressbar->set_size_request($progressbar_size, -1);
- $vbox->pack_start($progressbar, 0, 0, 0);
-
- change_mainw($vbox);
- my ($progress_nb, $download_nb);
- my $set_progressbar = sub {
- my ($local_ratio) = @_;
- if ($progress_nb || $download_nb) { # this happens when computing transaction
- $global_progressbar->set_fraction(($download_nb + $progress_nb - 1 + $local_ratio) / 2 / $urpm->{nb_install});
- }
- $progressbar->set_fraction($local_ratio);
- };
- my $callback_inst = sub {
- my ($urpm, $type, $id, $subtype, $amount, $total) = @_;
- my $pkg = defined $id ? $urpm->{depslist}[$id] : undef;
- if ($subtype eq 'start') {
- if ($type eq 'trans') {
- $progress_label->set_label(N("Preparing..."));
- } elsif ($pkg) {
- $progress_nb++;
- $download_nb = max($download_nb, $progress_nb);
- $set_progressbar->(0);
- $progress_label->set_label(
- N("Installing package `%s' (%s/%s)...", $pkg->name, $progress_nb, $urpm->{nb_install})
- );
- }
- } elsif ($subtype eq 'progress') {
- $set_progressbar->($amount / $total);
- }
- sync();
- };
+ $mainw->init_progressbar;
my $exit_code = urpm::main_loop::run($urpm, $state, scalar(@gurpmi::names), \@ask_unselect, {
bad_signature => sub {
@@ -354,38 +276,15 @@ sub do_install_3 () {
exit 1 if $response eq 'cancel';
1;
},
- trans_log => sub {
- my ($mode, $file, $percent, $total, $eta, $speed) = @_;
-
- urpm::download::sync_logger(@_);
-
- if (member($mode, 'start', 'progress')) {
- $file =~ s|/*\s*$||; $file =~ s|.*/||;
- $progress_label->set_label(N("Downloading package `%s'...", $file) . "\n" .
- &urpm::download::progress_text($mode, $percent, $total, $eta, $speed));
- }
- if ($mode eq 'start') {
- $download_nb++;
- $set_progressbar->(0);
- select(undef, undef, undef, 0.1); #- hackish
- } elsif ($mode eq 'progress') {
- $set_progressbar->($percent / 100);
- } elsif ($mode eq 'end') {
- $set_progressbar->(1);
- } elsif ($mode eq 'error') {
- #- error is 3rd argument, saved in $percent
- push @{$urpm->{download_errors}}, N("...retrieving failed: %s", $percent);
- }
- sync();
- },
+ trans_log => &gurpm::RPMProgressDialog::callback_download,
ask_yes_or_no => \&ask_yes_or_no,
completed => sub {
$urpmi_lock->unlock;
$rpm_lock->unlock;
urpm::removable::try_umounting_removables($urpm);
- $vbox = Gtk2::VBox->new(0, 5);
- $progress_label = Gtk2::Label->new('-');
+ my $vbox = Gtk2::VBox->new(0, 5); # FIXME: should it be change_widget???
+ my $progress_label = Gtk2::Label->new('-'); # TEST ME
return 0 if $gurpmi::options{auto};
my $sw = create_scrolled_window($progress_label);
$sw->set_size_request(500, 200);
@@ -393,7 +292,7 @@ sub do_install_3 () {
my $quit_button = Gtk2::Button->new(but(N("_Done")));
$quit_button->signal_connect(clicked => \&quit);
add_button_box($vbox, $quit_button);
- change_mainw($vbox);
+ $mainw->change_widget($vbox);
$mainw->set_focus($quit_button);
},
need_restart => sub {
@@ -407,24 +306,24 @@ sub do_install_3 () {
},
missing_files_summary => sub {
my ($error_sources) = @_;
- $progress_label->set_label(N("Installation failed, some files are missing:\n%s",
+ $mainw->set_progresslabel(N("Installation failed, some files are missing:\n%s",
join("\n", map { s|([^:]*://[^/:\@]*:)[^/:\@]*(\@.*)|$1xxxx$2|; " $_" }
values %$error_sources))
. "\n" . N("You may want to update your urpmi database."));
},
trans_error_summary => sub {
my ($_nok, $errors) = @_;
- $progress_label->set_label(N("Installation failed:") . "\n" . join("\n", map { "\t$_" } @$errors));
+ $mainw->set_progresslabel(N("Installation failed:") . "\n" . join("\n", map { "\t$_" } @$errors));
},
# TODO: use urpmi strings:
already_installed_or_not_installable => sub {
my ($_msg1, $_msg2) = @_;
- $progress_label->set_label(N("The package(s) are already installed"));
+ $mainw->set_progresslabel(N("The package(s) are already installed"));
},
- success_summary => sub { $progress_label->set_label(N("Installation finished")) },
- callback_report_uninst => sub { $progress_label->set_label(N("removing %s", $_[0])) },
- inst => $callback_inst,
- trans => $callback_inst,
+ success_summary => sub { $mainw->set_progresslabel(N("Installation finished")) },
+ callback_report_uninst => \&gurpm::RPMProgressDialog::callback_remove,
+ inst => \&gurpm::RPMProgressDialog::callback_inst,
+ trans => \&gurpm::RPMProgressDialog::callback_inst,
}
);
@@ -457,9 +356,4 @@ sub ask_yes_or_no {
$response eq 'yes';
}
-sub gtk_new_Label_Left {
- my ($text) = @_;
- my $w = Gtk2::Label->new($text);
- $w->set_alignment(0, 0);
- $w;
-}
+