diff options
-rw-r--r-- | Rpmdrake/gui.pm | 140 |
1 files changed, 73 insertions, 67 deletions
diff --git a/Rpmdrake/gui.pm b/Rpmdrake/gui.pm index 6da8ba4f..713d45ac 100644 --- a/Rpmdrake/gui.pm +++ b/Rpmdrake/gui.pm @@ -39,7 +39,7 @@ use Rpmdrake::pkg; use Rpmdrake::icon; use Gtk2::Gdk::Keysyms; -our @EXPORT = qw(ask_browse_tree_given_widgets_for_rpmdrake build_tree callback_choices closure_removal do_action get_info is_locale_available pkgs_provider reset_search switch_pkg_list_mode +our @EXPORT = qw(ask_browse_tree_given_widgets_for_rpmdrake build_tree callback_choices closure_removal do_action get_info is_locale_available pkgs_provider reset_search set_node_state switch_pkg_list_mode toggle_nodes $clear_button $dont_show_selections $find_entry $force_displaying_group $force_rebuild @initial_selection $pkgs $size_free $size_selected $urpm); our $dont_show_selections = $> ? 1 : 0; @@ -139,6 +139,67 @@ sub node_state { : ($urpm_obj->flag_base ? '/usr/share/rpmdrake/icons/base.png' : 'uninstalled')) : 'XXX'; } +my ($common, $w, %wtree, %ptree, %pix, %node_state, %state_stats); + +sub set_node_state_flat { + my ($iter, $state, $model) = @_; + print "STATE: $state\n"; + $state eq 'XXX' and return; + $pix{$state} ||= gtkcreate_pixbuf($state); + $model ||= $w->{tree_model}; + $model->set($iter, 1 => $pix{$state}); + $model->set($iter, 2 => $state); +} + +sub set_node_state_tree { + my ($iter, $state, $model) = @_; + $model ||= $w->{tree_model}; + my $iter_str = $model->get_path_str($iter); + ($state eq 'XXX' || !$state) and return; + $pix{$state} ||= gtkcreate_pixbuf('state_' . $state); + if ($node_state{$iter_str} ne $state) { + my $parent; + if (!$model->iter_has_child($iter) && ($parent = $model->iter_parent($iter))) { + my $parent_str = $model->get_path_str($parent); + my $stats = $state_stats{$parent_str} ||= {}; $stats->{$node_state{$iter_str}}--; $stats->{$state}++; + my @list = grep { $stats->{$_} > 0 } keys %$stats; + my $new_state = @list == 1 ? $list[0] : 'semiselected'; + $node_state{$parent_str} ne $new_state and + set_node_state_tree($parent, $new_state); + } + $model->set($iter, 1 => $pix{$state}); + $model->set($iter, 2 => $state); + #$node_state{$iter_str} = $state; #- cache for efficiency + } else { + } +} + +sub set_node_state { + $common->{state}{flat} ? set_node_state_flat(@_) : \&set_node_state_tree(@_); +} + +sub set_leaf_state { + my ($leaf, $state, $model) = @_; + set_node_state($_, $state, $model) foreach @{$ptree{$leaf}}; +} + +sub add_parent { + my ($root, $state) = @_; + $root or return undef; + if (my $w = $wtree{$root}) { return $w } + my $s; foreach (split '\|', $root) { + my $s2 = $s ? "$s|$_" : $_; + $wtree{$s2} ||= do { + my $pixbuf = get_icon($s2, $s); + my $iter = $w->{tree_model}->append_set($s ? add_parent($s, $state, get_icon($s)) : undef, [ 0 => $_, if_($pixbuf, 2 => $pixbuf) ]); + $iter; + }; + $s = $s2; + } + set_node_state($wtree{$s}, $state); #- use this state by default as tree is building. + $wtree{$s}; +} + # ask_browse_tree_given_widgets will run gtk+ loop. its main parameter "common" is a hash containing: # - a "widgets" subhash which holds: # o a "w" reference on a ugtk2 object @@ -153,75 +214,21 @@ sub node_state { # - "tree_mode": mode of the tree ("mandrake_choices", "by_group", ...) (mainly used by rpmdrake) sub ask_browse_tree_given_widgets_for_rpmdrake { - my ($common) = @_; - my $w = $common->{widgets}; + ($common) = @_; + $w = $common->{widgets}; $w->{detail_list} ||= $w->{tree}; $w->{detail_list_model} ||= $w->{tree_model}; my ($prev_label); - my (%wtree, %ptree, %pix, %node_state, %state_stats); my $update_size = sub { if ($w->{status}) { my $new_label = $common->{get_status}(); $prev_label ne $new_label and $w->{status}->set($prev_label = $new_label); } - }; - - my $set_node_state_flat = sub { - my ($iter, $state, $model) = @_; - $state eq 'XXX' and return; - $pix{$state} ||= gtkcreate_pixbuf($state); - $model ||= $w->{tree_model}; - $model->set($iter, 1 => $pix{$state}); - $model->set($iter, 2 => $state); - }; - my $set_node_state_tree; $set_node_state_tree = sub { - my ($iter, $state, $model) = @_; - $model ||= $w->{tree_model}; - my $iter_str = $model->get_path_str($iter); - ($state eq 'XXX' || !$state) and return; - $pix{$state} ||= gtkcreate_pixbuf('state_' . $state); - if ($node_state{$iter_str} ne $state) { - my $parent; - if (!$model->iter_has_child($iter) && ($parent = $model->iter_parent($iter))) { - my $parent_str = $model->get_path_str($parent); - my $stats = $state_stats{$parent_str} ||= {}; $stats->{$node_state{$iter_str}}--; $stats->{$state}++; - my @list = grep { $stats->{$_} > 0 } keys %$stats; - my $new_state = @list == 1 ? $list[0] : 'semiselected'; - $node_state{$parent_str} ne $new_state and - $set_node_state_tree->($parent, $new_state); - } - $model->set($iter, 1 => $pix{$state}); - $model->set($iter, 2 => $state); - #$node_state{$iter_str} = $state; #- cache for efficiency - } else { - } - }; - my $set_node_state = - $common->{state}{splited} || $common->{state}{flat} ? $set_node_state_flat : $set_node_state_tree; + }; - my $set_leaf_state = sub { - my ($leaf, $state, $model) = @_; - $set_node_state->($_, $state, $model) foreach @{$ptree{$leaf}}; - }; - my $add_parent; $add_parent = sub { - my ($root, $state) = @_; - $root or return undef; - if (my $w = $wtree{$root}) { return $w } - my $s; foreach (split '\|', $root) { - my $s2 = $s ? "$s|$_" : $_; - $wtree{$s2} ||= do { - my $pixbuf = get_icon($s2, $s); - my $iter = $w->{tree_model}->append_set($s ? $add_parent->($s, $state, get_icon($s)) : undef, [ 0 => $_, if_($pixbuf, 2 => $pixbuf) ]); - $iter; - }; - $s = $s2; - } - $set_node_state->($wtree{$s}, $state); #- use this state by default as tree is building. - $wtree{$s}; - }; - $common->{add_parent} = $add_parent; + $common->{add_parent} = \&add_parent; my $add_node = sub { my ($leaf, $root, $options) = @_; my $state = node_state($leaf) or return; @@ -229,13 +236,13 @@ sub ask_browse_tree_given_widgets_for_rpmdrake { my $iter; if (is_a_package($leaf)) { $iter = $w->{detail_list_model}->append_set([ 0 => $leaf ]); - $set_node_state->($iter, $state, $w->{detail_list_model}); + set_node_state($iter, $state, $w->{detail_list_model}); } else { - $iter = $w->{tree_model}->append_set($add_parent->($root, $state), [ 0 => $leaf ]); + $iter = $w->{tree_model}->append_set(add_parent($root, $state), [ 0 => $leaf ]); } push @{$ptree{$leaf}}, $iter; } else { - my $parent = $add_parent->($root, $state); + my $parent = add_parent($root, $state); #- hackery for partial displaying of trees, used in rpmdrake: #- if leaf is void, we may create the parent and one child (to have the [+] in front of the parent in the ctree) #- though we use '' as the label of the child; then rpmdrake will connect on tree_expand, and whenever @@ -265,7 +272,6 @@ sub ask_browse_tree_given_widgets_for_rpmdrake { }; $common->{rebuild_tree} = sub { $common->{delete_all}->(); - $set_node_state = $common->{state}{flat} ? $set_node_state_flat : $set_node_state_tree; $common->{build_tree}($add_node, $common->{state}{flat}, $common->{tree_mode}); &$update_size; }; @@ -331,13 +337,13 @@ sub ask_browse_tree_given_widgets_for_rpmdrake { #- not all is selected, select all if no option to potentially override (exists $common->{partialsel_unsel} && $common->{partialsel_unsel}->(\@unsel, \@l) ? difference2(\@l, \@unsel) : @unsel) : @l; - toggle_nodes($w->{tree}->window, $w->{detail_list_model}, $set_leaf_state, undef, @p); + toggle_nodes($w->{tree}->window, $w->{detail_list_model}, \&set_leaf_state, undef, @p); &$update_size; }; my $fast_toggle = sub { my ($iter) = @_; gtkset_mousecursor_wait($w->{w}{rwindow}->window); - $common->{check_interactive_to_toggle}($iter) and toggle_nodes($w->{tree}->window, $w->{detail_list_model}, $set_leaf_state, $w->{detail_list_model}->get($iter, 2), $w->{detail_list_model}->get($iter, 0)); + $common->{check_interactive_to_toggle}($iter) and toggle_nodes($w->{tree}->window, $w->{detail_list_model}, \&set_leaf_state, $w->{detail_list_model}->get($iter, 2), $w->{detail_list_model}->get($iter, 0)); &$update_size; gtkset_mousecursor_normal($w->{w}{rwindow}->window); }; @@ -364,7 +370,7 @@ sub ask_browse_tree_given_widgets_for_rpmdrake { }); $common->{rebuild_tree}->(); &$update_size; - $common->{initial_selection} and toggle_nodes($w->{tree}->window, $w->{detail_list_model}, $set_leaf_state, undef, @{$common->{initial_selection}}); + $common->{initial_selection} and toggle_nodes($w->{tree}->window, $w->{detail_list_model}, \&set_leaf_state, undef, @{$common->{initial_selection}}); #my $_b = before_leaving { $clear_all_caches->() }; $common->{init_callback}->() if $common->{init_callback}; $w->{w}->main; @@ -711,7 +717,7 @@ or you already installed all of them.")); # better loop on packages, create groups tree and push packages in the proper place: foreach my $pkg (@elems) { my $grp = $pkg->[1]; - $options->{add_parent}->($grp); + add_parent($grp); $elems->{$grp} ||= []; push @{$elems->{$grp}}, $pkg; } |