#!/usr/bin/perl # vim: set et ts=4 sw=4: # -*- coding: utf-8 -*- #***************************************************************************** # # Copyright (c) 2002 Guillaume Cottenceau # Copyright (c) 2002-2008 Thierry Vignaud # Copyright (c) 2003, 2004, 2005 MandrakeSoft SA # Copyright (c) 2005-2008 Mandriva SA # Copyright (c) 2013 Matteo Pasotti # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2, as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # #***************************************************************************** # # $Id: rpmdragora 267936 2010-04-26 16:40:21Z jvictor $ use File::ShareDir ':ALL'; use MDK::Common::Func qw(any if_ before_leaving); use utf8; use MDK::Common::DataStructure qw(uniq intersection); use MDK::Common::Various qw(to_bool first); use MDK::Common::System qw(arch); use urpm::media; use urpm::msg; use ManaTools::Rpmdragora::init; use ManaTools::rpmdragora; use ManaTools::Shared; use ManaTools::Shared::Locales; use ManaTools::Rpmdragora::open_db; use ManaTools::Rpmdragora::gui; use ManaTools::Rpmdragora::rpmnew; use ManaTools::Rpmdragora::formatting; use ManaTools::Rpmdragora::pkg; use yui; use feature 'state'; # OLD $ugtk2::wm_icon = get_icon('installremoverpm', "title-$MODE"); #TODO fix $wm_resource_path my $wm_resource_path="/usr/share/rpmdrake/icons"; my $wm_icon = "$wm_resource_path"."/title-$MODE.png"; # Declarations my $my_win; my $factory; my $mgaFactory; my $optFactory; my $extWidgets; my @itemsToBeRemoved; my @itemsToBeInstalled; our $w; our $statusbar; my $loc = ManaTools::rpmdragora::locale(); my %elems; sub _viewbox_callback { my ($selection, $options, $wanted_categories) = @_; state $old_index = -1; # TODO add a check on selection type YItem my $curr_index = $selection->index(); return 0 if $curr_index == $old_index; yui::YUI::app()->busyCursor(); $old_index = $curr_index; $default_list_mode = $options->{rviews}->[$curr_index]; # NOTE an undef value assignment produces a an array containing undef that is not a valid value to pass to # join into writeconf() @$mandrakeupdate_wanted_categories = $wanted_categories->{$options->{rviews}->[$curr_index]} ? @{$wanted_categories->{$options->{rviews}->[$curr_index]}} : (); if ($options->{tree_mode} ne $options->{rviews}->[$curr_index]) { $tree_mode->[0] = $options->{tree_mode} = $options->{rviews}->[$curr_index]; $tree_flat->[0] = $options->{state}{flat}; reset_search(); switch_pkg_list_mode($options->{rviews}->[$curr_index]); $options->{rebuild_tree}->(); } yui::YUI::app()->normalCursor(); return 1; } sub _filterbox_callback { my ($selection, $options, $rfilters) = @_; state $old_index = -1; # TODO add a check on selection type YItem my $curr_index = $selection->index(); return 0 if $curr_index == $old_index; yui::YUI::app()->busyCursor(); $old_index = $curr_index; my $val = $rfilters->[$curr_index]; if ($filter->[0] ne $val) { $filter->[0] = $val; reset_search(); slow_func(sub { switch_pkg_list_mode($default_list_mode) }); $options->{rebuild_tree}->(); } yui::YUI::app()->normalCursor(); return 1; } sub _searchmenu_callback { my ($selection, $options, $search_types, $current_search_type) = @_; state $old_index = -1; # TODO add a check on selection type YItem my $curr_index = $selection->index(); return 0 if $curr_index == $old_index; yui::YUI::app()->busyCursor(); $old_index = $curr_index; my $val = $search_types->[$curr_index]; if ($$current_search_type ne $val) { $$current_search_type = $val; reset_search(); slow_func(sub { switch_pkg_list_mode($default_list_mode) }); $options->{rebuild_tree}->(); } yui::YUI::app()->normalCursor(); return 1; } my $current_group = -1; sub _tree_callback { my ($selection, $options) = @_; #OLD my ($model, $iter) = $tree->currentItem(); #OLD return if !$iter; #state $current_group; #OLD my $new_group = $model->get_path_str($iter); #my $new_group = $selection->index(); #$current_group = -1 if(!defined($current_group)); #return if $current_group eq $new_group && !$force_displaying_group; undef $force_displaying_group; #$current_group = $new_group; #OLD $model && $iter or return; $selection or return; my $fullname = $selection->label(); my $it = $selection; while ($it = $it->parent()) { $fullname = join("|", $it->label(), $fullname); } my $group = $fullname; utf8::decode($group); if (!$selection->hasChildren()) { #$detail_list->window->freeze_updates; $options->{add_nodes}->(@{$elems{$group}}); #$detail_list->window->thaw_updates if $detail_list->window; } return; } sub _detaillist_changeditem_callback { my ($detail_list, $options) = @_; my $changedItem = $detail_list->changedItem(); return if (!$changedItem); fast_toggle($changedItem); return; } sub _detaillist_callback { my ($selection, $info, $options, $show_options) = @_; $info->setValue(""); return if( ref $selection ne "yui::YItem"); ManaTools::Rpmdragora::gui::setInfoOnWidget($options->{table_item_list}[$selection->index()], $info, $show_options); } sub _do_search($$$$$$) { my ($find_entry, $tree, $options, $current_search_type, $urpm, $pkgs) = @_; my $entry = $find_entry->value(); return if !$entry; if (!$use_regexp->[0]) { $entry = quotemeta $entry; # enable OR search by default: $entry =~ s/\\ /|/g if $current_search_type eq 'normal'; } # remove leading/trailing spacing when pasting: if ($entry !~ /\S\s\S/) { # if spacing in middle, likely a string search in description $entry =~ s/^\s*//; $entry =~ s/^\s*$//; } my $entry_rx = eval { qr/$entry/i } or return; reset_search(); # TODO FIXME speed up, we cannot remove an item but rebuilding all is slow # We could just rebuild the tree items $options->{rebuild_tree}->(); $options->{state}{flat} and $options->{delete_all}->(); # TODO: write a collapse_all method #$tree->collapse_all; my @search_results; if ($current_search_type eq 'normal') { my $count; foreach (@filtered_pkgs) { if ($NVR_searches->[0]) { next if !/$entry_rx/; } else { next if MDK::Common::Various::first(split_fullname($_)) !~ /$entry_rx/; } push @search_results, $_; # FIXME: should be done for all research types last if $count++ > 2000; } } elsif ($current_search_type eq 'summaries') { my $count; foreach (@filtered_pkgs) { next if get_summary($_) !~ /$entry_rx/; push @search_results, $_; # FIXME: should be done for all research types last if $count++ > 2000; } } else { my $searchstop; #my $searchw = ugtk2->new($loc->N("Software Management"), grab => 1, transient => $w->{real_window}); my $searchw = $factory->createPopupDialog; my $vbox = $factory->createVBox($searchw); my $lblWIP = $factory->createLabel($vbox, $loc->N("Please wait, searching...")); my $searchprogress = $factory->createProgressBar($vbox, ''); my $replace_pnt = $factory->createReplacePoint($vbox); # my $stop_button = $factory->createIconButton($vbox,"",$loc->N("Stop")); #gtkadd( #$searchw->{window}, #gtkpack__( #gtknew('VBox', spacing => 5), #gtknew('Label', text => $loc->N("Please wait, searching...")), #my $searchprogress = gtknew('ProgressBar', width => 300), #gtkpack__( #gtknew('HButtonBox', layout => 'spread'), #gtksignal_connect( #Gtk2::Button->new(but($loc->N("Stop"))), #clicked => sub { $searchstop = 1 }, #), #), #), #); #$searchw->sync; $searchw->recalcLayout(); $searchw->pollEvent(); # should probably not account backports packages or find a way to search them: my $total_size = scalar keys %$pkgs; my $progresscount = 0; my $update_search_pb = sub { $progresscount++; my $val = int($progresscount * 100 / $total_size); $searchprogress->setValue($val); $searchw->pollEvent() if $searchw->isTopmostDialog(); # refresh only if top most or crashing }; my $gurpm; # per medium download progress bar (if needed) my $_gurpm_clean_guard = MDK::Common::Func::before_leaving { undef $gurpm }; foreach my $medium (grep { !$_->{ignore} } @{$urpm->{media}}) { $searchstop and last; my $xml_info_file = urpm::media::any_xml_info($urpm, $medium, ($current_search_type eq 'files' ? 'files' : 'info'), undef, sub { $gurpm ||= ManaTools::Rpmdragora::gurpm->new( text => $loc->N("Please wait"), main_dialog => $searchw, parent => $replace_pnt, ); $gurpm->progress(0); download_callback($gurpm, @_) or do { $searchstop = 1; }; }); if (!$xml_info_file) { $urpm->{error}($loc->N("no xml-info available for medium \"%s\"", $medium->{name})); next; } $searchstop and last; require urpm::xml_info; require urpm::xml_info_pkg; $urpm->{log}("getting information from $xml_info_file"); if ($current_search_type eq 'files') { # special version for speed (3x faster), hopefully fully compatible my $F = urpm::xml_info::open_lzma($xml_info_file); my $fn; local $_; while (<$F>) { if ($searchstop) { statusbar_msg($loc->N("Search aborted"), 1); goto end_search; } if (m!^(); } elsif (/$entry_rx/) { $fn or $urpm->{fatal}("fast algorithm is broken, please report a bug"); push @search_results, $fn; } } } else { eval { urpm::xml_info::do_something_with_nodes( 'info', $xml_info_file, sub { $searchstop and die 'search aborted'; my ($node) = @_; $update_search_pb->(); push @search_results, $node->{fn} if $node->{description} =~ $entry_rx; #$searchstop and last; return 0 || $searchstop; }, ); }; my $err = $@; if ($err =~ /search aborted/) { statusbar_msg($loc->N("Search aborted"), 1); } } } end_search: @search_results = uniq(@search_results); #- there can be multiple packages with same version/release for different arch's @search_results = intersection(\@search_results, \@filtered_pkgs); $searchw->destroy; } # my $iter; if (@search_results) { @search_results = sort_packages(@search_results); $elems{$results_ok} = [ map { [ $_, $results_ok ] } @search_results ]; # $iter = $options->{add_parent}->($tree, $results_ok); ManaTools::Rpmdragora::gui::add_tree_item($tree, $results_ok, 1); $options->{add_nodes}->(map { [ $_, $results_ok . ($options->{tree_mode} eq 'by_presence' ? '|' . ($pkgs->{$_}{pkg}->flag_installed ? $loc->N("Upgradable") : $loc->N("Addable")) : ($options->{tree_mode} eq 'by_selection' ? '|' . ($pkgs->{$_}{selected} ? $loc->N("Selected") : $loc->N("Not selected")) : '')) ] } @search_results); } else { ManaTools::Rpmdragora::gui::add_tree_item($tree, $results_none, 1); # $iter = $options->{add_parent}->($tree, $results_none); # clear package list: $options->{add_nodes}->(); my $string = $default_list_mode eq 'all' && $filter->[0] eq 'all' ? $loc->N("No search results.") : $loc->N("No search results. You may want to switch to the '%s' view and to the '%s' filter", $loc->N("All"), $loc->N("All"),); statusbar_msg($string , 1); #gtkset_mousecursor_normal($::w->{rwindow}->window); } my $tree_selection = $tree->currentItem(); } sub _quit { real_quit(); } sub _run_treeview_dialog { my ($callback_action) = @_; my ($options, $tree, $detail_list, $detail_list_model); (undef, $size_free) = MDK::Common::System::df('/usr'); # OLD $::main_window = $w->{real_window}; $::main_window = $my_win; $size_selected = 0; $options = { build_tree => sub { build_tree($tree, \%elems, $options, $force_rebuild, @_) }, partialsel_unsel => sub { my ($unsel, $sel) = @_; @$sel = grep { exists $pkgs->{$_} } @$sel; @$unsel < @$sel; }, get_status => sub { $loc->N("Selected: %s / Free disk space: %s", urpm::msg::formatXiB($size_selected), urpm::msg::formatXiB($size_free*1024)); }, rebuild_tree => sub { $tree->rebuildTree(); }, }; my $vbox = $factory->createVBox($my_win); my $hbox_headbar = $factory->createHBox($vbox); my $head_align_left = $factory->createLeft($hbox_headbar); my $head_align_right = $factory->createRight($hbox_headbar); my $headbar = $factory->createHBox($head_align_left); my $headRight = $factory->createHBox($head_align_right); #Line for logo and title my $hbox_iconbar = $factory->createHBox($vbox); $head_align_left = $factory->createLeft($hbox_iconbar); $hbox_iconbar = $factory->createHBox($head_align_left); $factory->createImage($hbox_iconbar, $wm_icon); $factory->createHeading($hbox_iconbar, $::MODE eq 'update' ? $loc->N("Software Packages Update") : $loc->N("Software Management")); my $hbox_top = $factory->createHBox($vbox); my $hbox_middle = $factory->createHBox($vbox); my $hbox_bottom = $factory->createHBox($vbox); my $hbox_footbar = $factory->createHBox($vbox); $hbox_headbar->setWeight(1,10); $hbox_top->setWeight(1,10); $hbox_middle->setWeight(1,50); $hbox_bottom->setWeight(1,30); $hbox_footbar->setWeight(1,10); # Tree for groups $tree = $factory->createTree($hbox_middle, ""); $tree->setWeight(0,20); $tree->setNotify(1); my $detail_list_header = new yui::YTableHeader(); my $display_arch_col = to_bool(arch() =~ /64/); my @columns = (qw(name summary version release), if_($display_arch_col, 'arch')); my %columns = ( 'name' => { title => $loc->N("Package"), markup => $pkg_columns{short_name}, }, 'summary' => { title => $loc->N("Summary"), }, 'version' => { title => $loc->N("Version"), text => $pkg_columns{version}, }, 'release' => { title => $loc->N("Release"), text => $pkg_columns{release}, }, if_($display_arch_col, 'arch' => { title => #-PO: "Architecture" but to be kept *small* !!! $loc->N("Arch."), text => $pkg_columns{arch}, }), 'mark' => { title => $loc->N("ToInst"), } ); ## check column is first no title needed here, but we need to add it $detail_list_header->addColumn(""); foreach my $col (@columns{@columns}) { $detail_list_header->addColumn($col->{title}); } $detail_list_header->addColumn($loc->N("Status")); $detail_list = $mgaFactory->createCBTable($hbox_middle,$detail_list_header,$yui::YCBTableCheckBoxOnFirstColumn); $detail_list->setWeight(0,50); $detail_list->setImmediateMode(1); =for comment my $cursor_to_restore; $_->signal_connect( expose_event => sub { $cursor_to_restore or return; gtkset_mousecursor_normal($tree->window); undef $cursor_to_restore; },) foreach $tree, $detail_list; $tree->currentItem(changed => sub { my ($model, $iter) = $_[0]->get_selected; return if !$iter; state $current_group; my $new_group = $model->get_path_str($iter); return if $current_group eq $new_group && !$force_displaying_group; undef $force_displaying_group; $current_group = $new_group; $model && $iter or return; my $group = $model->get($iter, 0); my $parent = $iter; while ($parent = $model->iter_parent($parent)) { $group = join('|', $model->get($parent, 0), $group); } $detail_list->window->freeze_updates; $options->{add_nodes}->(@{$elems{$group}}); $detail_list->window->thaw_updates if $detail_list->window; }); =cut $options->{state}{splited} = 1; $options->{state}{flat} = $tree_flat->[0]; my $is_backports = get_inactive_backport_media(fast_open_urpmi_db()); my %filters = ( all => $loc->N("All"), installed => $loc->N("Installed"), non_installed => $loc->N("Not installed"), ); my @ordered_filters = (qw (all installed non_installed) ); # handle migrating config file from rpmdragora <= 4.9 if (exists $filters{$default_list_mode}) { $filter->[0] = $default_list_mode; $default_list_mode = 'all'; } $options->{tree_mode} = $default_list_mode; my %modes = ( flat => $loc->N("All packages, alphabetical"), by_group => $loc->N("All packages, by group"), by_leaves => $loc->N("Leaves only, sorted by install date"), by_presence => $loc->N("All packages, by update availability"), by_selection => $loc->N("All packages, by selection state"), by_size => $loc->N("All packages, by size"), by_source => $loc->N("All packages, by medium repository"), ); my %views = ( all => $loc->N("All"), if_($is_backports, backports => $loc->N("Backports")), meta_pkgs => $loc->N("Meta packages"), gui_pkgs => $loc->N("Packages with GUI"), all_updates => $loc->N("All updates"), security => $loc->N("Security updates"), bugfix => $loc->N("Bugfixes updates"), normal => $loc->N("General updates") ); my @ordered_views = (qw (all meta_pkgs gui_pkgs all_updates security normal) ); push @ordered_views, 'backports' if $is_backports; $options->{rviews} = \@ordered_views; my %default_mode = (install => 'all', # we want the new GUI by default instead of "non_installed" remove => 'installed', update => 'security', ); my %wanted_categories = ( all_updates => [ qw(security bugfix normal) ], security => [ 'security' ], bugfix => [ 'bugfix' ], normal => [ 'normal' ], ); my $view_box = $factory->createComboBox($hbox_top,""); my $itemColl = new yui::YItemCollection; foreach (@ordered_views) { my $item = yui::YItem->new("$views{$_}", 0); $item->setSelected(1) if defined($views{$default_list_mode}) && $_ eq $default_list_mode; $itemColl->push($item); $item->DISOWN(); } $view_box->addItems($itemColl); $view_box->setNotify(1); $options->{tree_submode} ||= $default_list_mode; $options->{tree_subflat} ||= $options->{state}{flat}; my $filter_box = $factory->createComboBox($hbox_top,""); $itemColl = new yui::YItemCollection; foreach (@ordered_filters) { my $item = yui::YItem->new("$filters{$_}", 0); $item->setSelected(1) if defined($filters{$filter->[0]}) && $_ eq $filter->[0]; $itemColl->push($item); $item->DISOWN(); } $filter_box->addItems($itemColl); $filter_box->setNotify(1); my %local_search_types = ( normal => $loc->N("in names"), descriptions => $loc->N("in descriptions"), summaries => $loc->N("in summaries"), files => $loc->N("in file names"), ); my @search_types = ( qw(normal descriptions summaries files) ); my $current_search_type = $search_types[0]; my $search_menu = $factory->createComboBox($hbox_top,""); $itemColl = new yui::YItemCollection; foreach (@search_types) { my $item = yui::YItem->new("$local_search_types{$_}", 0); $item->setSelected(1) if defined($local_search_types{$current_search_type}) && $_ eq $current_search_type; $itemColl->push($item); $item->DISOWN(); } $search_menu->addItems($itemColl); $search_menu->setNotify(1); $find_entry = $factory->createInputField($hbox_top, ""); my $icon_file = File::ShareDir::dist_file(ManaTools::Shared::distName(), "images/manalog.png"); my $find_button = $factory->createIconButton($hbox_top, $icon_file, $loc->N("Search")); $find_button->setWeight(0,6); $my_win->setDefaultButton($find_button); $icon_file = File::ShareDir::dist_file(ManaTools::Shared::distName(), "images/rpmdragora/clear_22x22.png"); my $reset_search_button = $factory->createIconButton($hbox_top, $icon_file, $loc->N("Reset")); $reset_search_button->setWeight(0,7); $find_entry->setWeight(0,10); #OLD my $info = Gtk2::Mdv::TextView->new; #my $info = $factory->createMultiLineEdit($hbox_bottom,""); my $info = $factory->createRichText($hbox_bottom,""); #$info->setDisabled(); $info->setWeight(0,40); $info->setWeight(1,40); #OLD $info->set_left_margin(2); #OLD $info->set_right_margin(15); #- workaround when right elevator of scrolled window appears my $find_callback = sub { _do_search($find_entry, $tree, $options, $current_search_type, $urpm, $pkgs); }; my $select_all_button = $factory->createIconButton($hbox_footbar,"",$loc->N("Select all")); $select_all_button->setWeight(0,6); my $apply_button = $factory->createIconButton($hbox_footbar,"",$loc->N("Apply")); $apply_button->setWeight(0,6); my $QuitButton = $factory->createIconButton($hbox_footbar,"",$loc->N("Exit")); $QuitButton->setWeight(0,6); #my $hpaned = gtknew('HPaned', position => $typical_width*0.9, # child1 => gtknew('ScrolledWindow', child => $tree), # resize1 => 0, shrink1 => 0, # resize2 => 1, shrink2 => 0, # child2 => gtknew('VPaned', # child1 => gtknew('ScrolledWindow', child => $detail_list), resize1 => 1, shrink1 => 0, # child2 => gtknew('ScrolledWindow', child => $info), resize2 => 1, shrink2 => 0 # ) # ); my $reload_db_and_clear_all = sub { slow_func(sub { $force_rebuild = 1; ManaTools::Rpmdragora::gui::pkgs_provider($options->{tree_mode}, skip_updating_mu => 1); ManaTools::Rpmdragora::gui::reset_search(); $size_selected = 0; $options->{rebuild_tree}->(); $find_callback->(); }); }; #OLD my $status = gtknew('Label'); my $status = $factory->createLabel($vbox, ""); my $checkbox_show_autoselect; my %check_boxes; my $auto_select_string = $loc->N("/_Options") . $loc->N("/_Select dependencies without asking"); my $clean_cache_string = $loc->N("/_Options") . "/" . $loc->N("Clear download cache after successful install"); my $updates_string = $loc->N("/_Options") . $loc->N("/_Compute updates on startup"); my $NVR_string = $loc->N("/_Options") . "/" . $loc->N("Search in _full package names"); my $regexp_search_string = $loc->N("/_Options") . "/" . $loc->N("Use _regular expressions in searches"); $itemColl = new yui::YItemCollection; # build File menu my %fileMenu = ( widget => $factory->createMenuButton($headbar,$loc->N("File")), update => new yui::YMenuItem($loc->N("Update media")), reset_sel => new yui::YMenuItem($loc->N("Reset the selection")), reload => new yui::YMenuItem($loc->N("Reload the packages list")), quit => new yui::YMenuItem($loc->N("&Quit")), ); my @ordered_menu_lines = qw(update reset_sel reload quit); foreach (@ordered_menu_lines) { $itemColl->push($fileMenu{ $_ }); $fileMenu{$_}->DISOWN(); } $fileMenu{ widget }->addItems($itemColl); $fileMenu{ widget }->rebuildMenuTree(); $itemColl->clear(); # build Settings (old Options) menu my $settings_menu = $factory->createMenuButton($headbar,$loc->N("Settings")); my %settingsMenuLabel = ( media_manager => $loc->N("&Media Manager"), options => $loc->N("Options"), ); @ordered_menu_lines = qw( media_manager options ); foreach my $lbl (@ordered_menu_lines) { my $item = new yui::YMenuItem($settingsMenuLabel{ $lbl }); $itemColl->push($item); $item->DISOWN(); } $settings_menu->addItems($itemColl); $settings_menu->rebuildMenuTree(); $itemColl->clear(); =for comment my $a_s_string = $auto_select_string; my $c_c_string = $clean_cache_string; # stripping gtk-related stuff $a_s_string =~s/\/.+\/_//g; $c_c_string =~s/\/.+\/_//g; my $optMnuItemAutoSelect = new yui::YMenuItem($a_s_string); my $optMnuItemCleanCache = new yui::YMenuItem($c_c_string); $settings_menu->addItem($optMnuItemAutoSelect); $settings_menu->addItem($optMnuItemCleanCache); $settings_menu->rebuildMenuTree(); =cut # build View menu my $view_menu = $factory->createMenuButton($headbar,$loc->N("View")); # build help menu my %helpMenu = ( widget => $factory->createMenuButton($headRight, $loc->N("&Help")), help => new yui::YMenuItem($loc->N("Manual")), report_bug => new yui::YMenuItem($loc->N("Report Bug")), about => new yui::YMenuItem($loc->N("&About")), ); @ordered_menu_lines = qw(help report_bug about); foreach (@ordered_menu_lines) { $helpMenu{ widget }->addItem($helpMenu{ $_ }); } $helpMenu{ widget }->rebuildMenuTree(); $statusbar = $factory->createBusyIndicator($hbox_footbar, "" ); =for comment my ($menu, $factory) = create_factory_menu( $w->{real_window}, [ $loc->N("/_File"), undef, undef, undef, '' ], if_( ! $>, [ $loc->N("/_File") . $loc->N("/_Update media"), undef, sub { update_sources_interactive($urpm, transient => $w->{real_window}) and $reload_db_and_clear_all->(); }, undef, '' ] ), [ $loc->N("/_File") . $loc->N("/_Reset the selection"), undef, sub { if ($MODE ne 'remove') { my $db = eval { open_rpm_db() }; if (!ref($db)) { statusbar_msg($loc->N("Reset aborted (RPM DB is locked by another process)"), 1); return; } $urpm->disable_selected( $db, $urpm->{state}, map { if_($pkgs->{$_}{selected}, $pkgs->{$_}{pkg}) } keys %$pkgs, ); } undef $pkgs->{$_}{selected} foreach keys %$pkgs; reset_search(); $size_selected = 0; $force_displaying_group = 1; my $tree_selection = $tree->get_selection; $tree_selection->select_path(Gtk2::TreePath->new_from_string('0')) if !$tree_selection->get_selected; $tree_selection->signal_emit('changed'); }, undef, '' ], [ $loc->N("/_File") . $loc->N("/Reload the _packages list"), undef, $reload_db_and_clear_all, undef, '' ], [ $loc->N("/_File") . $loc->N("/_Quit"), $loc->N("Q"), \&quit, undef, '', ], #[ $loc->N("/_View"), undef, undef, undef, '' ], if_(!$>, [ $loc->N("/_Options"), undef, undef, undef, '' ], [ $auto_select_string, undef, sub { my $box = $check_boxes{$auto_select_string}; $auto_select->[0] = $box->get_active; $::rpmdragora_options{auto} = $box->get_active; $urpm->{options}{auto} = $box->get_active; }, undef, '' ], [ $clean_cache_string, undef, sub { $clean_cache->[0] = $check_boxes{$clean_cache_string}->get_active; $::noclean = !$clean_cache->[0]; }, undef, '' ], [ $loc->N("/_Options") . $loc->N("/_Media Manager"), undef, sub { require ManaTools::Rpmdragora::edit_urpm_sources; ManaTools::Rpmdragora::edit_urpm_sources::run() && $reload_db_and_clear_all->(); }, undef, '' ], [ $loc->N("/_Options") . $loc->N("/_Show automatically selected packages"), undef, sub { $dont_show_selections->[0] = !$checkbox_show_autoselect->get_active; }, undef, '' ], [ $updates_string, undef, sub { $compute_updates->[0] = $check_boxes{$updates_string}->get_active; }, undef, '' ], [ $NVR_string, undef, sub { $NVR_searches->[0] = $check_boxes{$NVR_string}->get_active; }, undef, '' ], [ $regexp_search_string, undef, sub { $use_regexp->[0] = $check_boxes{$regexp_search_string}->get_active; }, undef, '' ], ), [ $loc->N("/_View"), undef, undef, undef, '' ], (map { state ($idx, $previous); my $type = $idx ? join('/', $loc->N("/_View"), $previous) : ''; $type =~ s/_//g; # gtk+ retrieve widgets by their path w/o any shortcut marks $previous = $modes{$_}; $idx++; my $val = $_; [ $loc->N("/_View") . '/' . $modes{$_}, undef, sub { $view_callback->($val) }, 0, $type ]; } qw(flat by_group by_leaves by_presence by_selection by_size by_source)), [ $loc->N("/_Help"), undef, undef, undef, '' ], [ $loc->N("/_Help") . $loc->N("/_Report Bug"), undef, sub { run_drakbug('rpmdragora') }, undef, '' ], [ $loc->N("/_Help") . $loc->N("/_Help"), undef, sub { ManaTools::rpmdragora::open_help('') }, undef, '' ], [ $loc->N("/_Help") . $loc->N("/_About..."), undef, sub { my $license = formatAlaTeX(translate($::license)); $license =~ s/\n/\n\n/sg; # nicer formatting my $w = gtknew('AboutDialog', name => $loc->N("Rpmdragora"), version => $ManaTools::Rpmdragora::init::version, copyright => $loc->N("Copyright (C) %s by Mandriva", '2002-2009')."\n".$loc->N("Copyright (C) %s by Mageia.Org", '2010-2013'), license => $license, wrap_license => 1, comments => $loc->N("Rpmdragora is the Mageia package management tool."), website => 'http://www.mageia.org', website_label => $loc->N("Mageia"), authors => "Thierry Vignaud \nAngelo Naselli \nMatteo Pasotti ", artists => 'Hélène Durosini ', translator_credits => #-PO: put here name(s) and email(s) of translator(s) (eg: "John Smith ") $loc->N("_: Translator(s) name(s) & email(s)\n"), transient_for => $::main_window, modal => 1, position_policy => 'center-on-parent', ); $w->show_all; $w->run; }, undef, '' ] ); # to retrieve a path, one must prevent "accelerators completion": my $get_path = sub { return join('', map { my $i = $_; $i =~ s/_//g; $i } @_) }; if (my $widget = $factory->get_item('
' . $get_path->($loc->N("/_View") . '/' . $modes{$mode->[0]}))) { $widget->set_active(1); } else { warn "Impossible to set $mode->[0] view as default\n"; } %check_boxes = map { $_ => $factory->get_widget("
" . $get_path->($_)); } ($auto_select_string, $clean_cache_string, $NVR_string, $updates_string, $regexp_search_string); if (!$>) { $check_boxes{$regexp_search_string}->set_active($use_regexp->[0]); $check_boxes{$NVR_string}->set_active($NVR_searches->[0]); $check_boxes{$auto_select_string}->set_active($auto_select->[0]); $check_boxes{$updates_string}->set_active($compute_updates->[0]); $check_boxes{$clean_cache_string}->set_active($clean_cache->[0]); } $checkbox_show_autoselect = $factory->get_widget("
" . strip_first_underscore($loc->N("/_Options"), $loc->N("/_Show automatically selected packages"))) and $checkbox_show_autoselect->set_active(!$dont_show_selections->[0]); my $accel = Gtk2::AccelGroup->new; $accel->connect(Gtk2::Gdk->keyval_from_name('F'), [ 'control-mask' ], [ 'visible' ], sub { $find_entry->grab_focus }); $w->{real_window}->add_accel_group($accel); gtkadd( $w->{window}, gtkpack_( gtknew('VBox', spacing => 3), 0, $menu, if_(second(gtkroot()->get_size) >= 600, 0, getbanner()), 1, gtkadd( gtknew('Frame', border_width => 3, shadow_type => 'none'), gtkpack_( gtknew('VBox', spacing => 3), 0, gtkpack_( gtknew('HBox', spacing => 10), 0, $view_box, 0, $filter_box, 0, gtknew('Label', text => $loc->N("Find:")), 1, $find_entry = gtknew('Entry', width => 260, primary_icon => 'gtk-find', secondary_icon => 'gtk-clear', tip => $loc->N("Please type in the string you want to search then press the key"), 'icon-release' => $find_callback, 'icon-press' => sub { my (undef, $pos, $event) = @_; # emulate Sexy::IconEntry's clear_button: if ($pos eq 'secondary') { $find_entry->set_text(''); reset_search(); } return if $pos ne 'primary'; $search_menu->popup(undef, undef, undef, undef, $event->button, $event->time); }, key_press_event => sub { member($_[1]->keyval, $Gtk2::Gdk::Keysyms{Return}, $Gtk2::Gdk::Keysyms{KP_Enter}) and $find_callback->(); }, ), ), 1, $hpaned, 0, $status, 0, gtkpack_( gtknew('HBox', spacing => 20), 0, gtksignal_connect( Gtk2::Button->new(but_($loc->N("Select all"))), clicked => sub { toggle_all($options, 1); }, ), 1, gtknew('Label'), 0, my $action_button = gtksignal_connect( Gtk2::Button->new(but_($loc->N("Apply"))), clicked => sub { do_action($options, $callback_action, $info) }, ), 0, gtksignal_connect( Gtk2::Button->new(but_($loc->N("Quit"))), clicked => \&quit, ), ), ), ), 0, $statusbar = Gtk2::Statusbar->new, ), ); $action_button->set_sensitive(0) if $>; $find_entry->grab_focus; gtktext_insert($info, [ [ $info->render_icon('gtk-dialog-info', 'GTK_ICON_SIZE_DIALOG', undef) ], @{ ugtk2::markup_to_TextView_format( formatAlaTeX(join("\n\n\n", format_header($loc->N("Quick Introduction")), $loc->N("You can browse the packages through the categories tree on the left."), $loc->N("You can view information about a package by clicking on it on the right list."), $loc->N("To install, update or remove a package, just click on its \"checkbox\".")))) } ]); $w->{rwindow}->set_default_size($typical_width*2.7, 500) if !$::isEmbedded; =cut $find_entry->setText($rpmdragora_options{search}[0]) if $rpmdragora_options{search}; #if ($rpmdragora_width->[0] && $rpmdragora_height->[0]) { ## so that we can shrink back: #$w->{real_window}->set_default_size($rpmdragora_width->[0], $rpmdragora_height->[0]); #} #$w->{rwindow}->show_all; #$w->{rwindow}->set_sensitive(0); # ensure treeview get realized so that ->get_selection returns something #$detail_list->realize; #gtkflush(); #OLD slow_func($::main_window->window, sub { pkgs_provider($default_list_mode) }); # default mode slow_func(sub { pkgs_provider($default_list_mode) }); # default mode if (@initial_selection) { print "\n== Initial selection: @initial_selection\n"; $options->{initial_selection} = \@initial_selection; undef $pkgs->{$_}{selected} foreach @initial_selection; } #$w->{rwindow}->set_sensitive(1); $options->{widgets} = { w => $my_win, tree => $tree, #detail_list_model => $detail_list_model, detail_list => $detail_list, info => $info, status => $status, }; $options->{init_callback} = $find_callback if $rpmdragora_options{search}; ask_browse_tree_given_widgets_for_rpmdragora($options); my $info_options = {}; # select group and show items evenctually _tree_callback($tree->currentItem(),\%$options); ######## main loop #################### while(1) { my $event = $my_win->waitForEvent(); my $eventType = $event->eventType(); #event type checking if ($eventType == $yui::YEvent::CancelEvent) { last if _quit(); } elsif ($eventType == $yui::YEvent::MenuEvent) { ### MENU ### my $item = $event->item(); if (!$item) { #URL emitted or at least a ref into RichText widget my $url = yui::toYMenuEvent($event)->id (); if (ManaTools::Rpmdragora::gui::info_details($url, $info_options) ) { $item = $detail_list->selectedItem(); _detaillist_callback($item, $info, \%$options, $info_options); } else { # default it's really a URL ManaTools::Rpmdragora::gui::run_browser($url); } } else { my $menuLabel = $item->label(); print "Menu " . $menuLabel . " chosen\n"; if ($menuLabel eq $fileMenu{ quit }->label()) { #menu File->Quit last if _quit(); } elsif ($menuLabel eq $fileMenu{ update }->label()) { update_sources_interactive($urpm, transient => $my_win) and $reload_db_and_clear_all->(); } elsif ($menuLabel eq $fileMenu{ reset_sel }->label()) { if ($MODE ne 'remove') { my $db = eval { open_rpm_db() }; if (!ref($db)) { statusbar_msg($loc->N("Reset aborted (RPM DB is locked by another process)"), 1); last; } $urpm->disable_selected( $db, $urpm->{state}, map { if_($pkgs->{$_}{selected}, $pkgs->{$_}{pkg}) } keys %$pkgs,); } undef $pkgs->{$_}{selected} foreach keys %$pkgs; reset_search(); $size_selected = 0; $force_displaying_group = 1; my $tree_selection = $tree->currentItem(); } elsif ($menuLabel eq $fileMenu{ reload }->label()) { $reload_db_and_clear_all->(); } elsif ($menuLabel eq $settingsMenuLabel{media_manager}) { require ManaTools::Rpmdragora::edit_urpm_sources; ManaTools::Rpmdragora::edit_urpm_sources::run() && $reload_db_and_clear_all->(); } elsif ($menuLabel eq $settingsMenuLabel{options}) { } elsif ($menuLabel eq $helpMenu{ about }->label()) { my $translators = $loc->N("_: Translator(s) name(s) & email(s)\n"); $translators =~ s/\/\>\;/g; my $sh_gui = ManaTools::Shared::GUI->new(); $sh_gui->AboutDialog({ name => "Rpmdragora", version => $VERSION, credits => $loc->N("Copyright (C) %s Mageia community", '2013-2014'), license => $loc->N("GPLv2"), description => $loc->N("Rpmdragora is the Mageia package management tool."), authors => $loc->N("

Developers

  • %s
  • %s

Translators

  • %s
", "Angelo Naselli <anaselli\@linux.it>", "Matteo Pasotti <matteo.pasotti\@gmail.com>", $translators ), } ); } } } elsif ($eventType == $yui::YEvent::WidgetEvent) { # widget selected my $widget = $event->widget(); my $perform_search = 0; if($widget == $reset_search_button) { $find_entry->setValue(''); reset_search(); $options->{rebuild_tree}->(); } elsif ($widget == $find_button) { $perform_search = 1; } elsif ($widget == $select_all_button) { toggle_all($options, 1); #select_all_current_packages(\$detail_list); } elsif ($widget == $apply_button) { do_action($options, $callback_action, $info); } elsif ($widget == $view_box) { if (_viewbox_callback($view_box->selectedItem(), \%$options, \%wanted_categories)) { $perform_search = 1 if $find_entry->value(); } } elsif ($widget == $filter_box) { if (_filterbox_callback($filter_box->selectedItem(), \%$options, \@ordered_filters)) { $perform_search = 1 if $find_entry->value(); } } elsif ($widget == $search_menu) { if (_searchmenu_callback($search_menu->selectedItem(), \%$options, \@search_types, \$current_search_type)) { $perform_search = 1 if $find_entry->value(); } } elsif ($widget == $tree) { _tree_callback($tree->currentItem(),\%$options); } elsif ($widget == $detail_list){ $info_options = {}; my $wEvent = yui::toYWidgetEvent($event); if ($wEvent->reason() == $yui::YEvent::ValueChanged) { yui::YUI::app()->busyCursor(); _detaillist_changeditem_callback($detail_list, \%$options); yui::YUI::app()->normalCursor(); _tree_callback($tree->currentItem(),\%$options); } _detaillist_callback($detail_list->selectedItem(), $info, \%$options); } elsif ($widget == $QuitButton) { last if _quit(); } if ($perform_search) { yui::YUI::app()->busyCursor(); _do_search($find_entry, $tree, $options, $current_search_type, $urpm, $pkgs); yui::YUI::app()->normalCursor(); $perform_search = 0; } } } $my_win->destroy } # -=-=-=---=-=-=---=-=-=-- main -=-=-=---=-=-=---=-=-=- if (my $pid = ManaTools::Shared::isProcessRunning('rpmdragora')) { interactive_msg($loc->N("Warning"), $loc->N("rpmdragora is already running (pid: %s)", $pid), yesno => [ $loc->N("Quit") ]); exit(0); } if(!warn_about_user_mode()) { exit(0); } yui::YUI::app()->setApplicationTitle($loc->N("Software Management")); yui::YUI::app()->setApplicationIcon($wm_icon); my $MGAPlugin = "mga"; $factory = yui::YUI::widgetFactory; $mgaFactory = yui::YExternalWidgets::externalWidgetFactory($MGAPlugin); $mgaFactory = yui::YMGAWidgetFactory::getYMGAWidgetFactory($mgaFactory); $optFactory = yui::YUI::optionalWidgetFactory; ### MAIN DIALOG ### $my_win = $factory->createMainDialog; readconf(); ManaTools::Rpmdragora::rpmnew::do_merge_if_needed(); init(); _run_treeview_dialog(\&perform_installation); writeconf(); 1;