/[soft]/rpmdrake/trunk/rpmdrake
ViewVC logotype

Contents of /rpmdrake/trunk/rpmdrake

Parent Directory Parent Directory | Revision Log Revision Log


Revision 979 - (show annotations) (download)
Fri Apr 22 16:20:01 2011 UTC (13 years ago) by ahmad
File size: 32472 byte(s)
- s/successfull/successful/ (mga#945)

1 #!/usr/bin/perl
2 # -*- coding: utf-8 -*-
3 #*****************************************************************************
4 #
5 # Copyright (c) 2002 Guillaume Cottenceau
6 # Copyright (c) 2002-2008 Thierry Vignaud <tvignaud@mandriva.com>
7 # Copyright (c) 2003, 2004, 2005 MandrakeSoft SA
8 # Copyright (c) 2005-2008 Mandriva SA
9 #
10 # This program is free software; you can redistribute it and/or modify
11 # it under the terms of the GNU General Public License version 2, as
12 # published by the Free Software Foundation.
13 #
14 # This program is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 # GNU General Public License for more details.
18 #
19 # You should have received a copy of the GNU General Public License
20 # along with this program; if not, write to the Free Software
21 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 #
23 #*****************************************************************************
24 #
25 # $Id: rpmdrake 267936 2010-04-26 16:40:21Z jvictor $
26
27 use strict;
28 use MDK::Common::Func 'any';
29 use lib qw(/usr/lib/libDrakX);
30 use common;
31 use utf8;
32
33 use Rpmdrake::init;
34 use standalone; #- standalone must be loaded very first, for 'explanations', but after rpmdrake::init
35 use rpmdrake;
36 use Rpmdrake::open_db;
37 use Rpmdrake::gui;
38 use Rpmdrake::rpmnew;
39 use Rpmdrake::formatting;
40 use Rpmdrake::pkg;
41 use urpm::media;
42
43 use mygtk2 qw(gtknew); #- do not import anything else, especially gtkadd() which conflicts with ugtk2 one
44 use ugtk2 qw(:all);
45 use Gtk2::Gdk::Keysyms;
46 use Rpmdrake::widgets;
47 use feature 'state';
48
49 $ugtk2::wm_icon = get_icon('installremoverpm', "title-$MODE");
50
51 our $w;
52 our $statusbar;
53
54 my %elems;
55
56 sub do_search($$$$$$$) {
57 my ($find_entry, $tree, $tree_model, $options, $current_search_type, $urpm, $pkgs) = @_;
58 my $entry = $find_entry->get_text or return;
59 if (!$use_regexp->[0]) {
60 $entry = quotemeta $entry;
61 # enable OR search by default:
62 $entry =~ s/\\ /|/g if $current_search_type eq 'normal';
63 }
64 # remove leading/trailing spacing when pasting:
65 if ($entry !~ /\S\s\S/) {
66 # if spacing in middle, likely a string search in description
67 $entry =~ s/^\s*//;
68 $entry =~ s/^\s*$//;
69 }
70 my $entry_rx = eval { qr/$entry/i } or return;
71 reset_search();
72 $options->{state}{flat} and $options->{delete_all}->();
73 $tree->collapse_all;
74 my @search_results;
75 if ($current_search_type eq 'normal') {
76 my $count;
77 foreach (@filtered_pkgs) {
78 if ($NVR_searches->[0]) {
79 next if !/$entry_rx/;
80 } else {
81 next if first(split_fullname($_)) !~ /$entry_rx/;
82 }
83 push @search_results, $_;
84 # FIXME: should be done for all research types
85 last if $count++ > 2000;
86 }
87 } elsif ($current_search_type eq 'summaries') {
88 my $count;
89 foreach (@filtered_pkgs) {
90 next if get_summary($_) !~ /$entry_rx/;
91 push @search_results, $_;
92 # FIXME: should be done for all research types
93 last if $count++ > 2000;
94 }
95 } else {
96 my $searchstop;
97 my $searchw = ugtk2->new(N("Software Management"), grab => 1, transient => $w->{real_window});
98 gtkadd(
99 $searchw->{window},
100 gtkpack__(
101 gtknew('VBox', spacing => 5),
102 gtknew('Label', text => N("Please wait, searching...")),
103 my $searchprogress = gtknew('ProgressBar', width => 300),
104 gtkpack__(
105 gtknew('HButtonBox', layout => 'spread'),
106 gtksignal_connect(
107 Gtk2::Button->new(but(N("Stop"))),
108 clicked => sub { $searchstop = 1 },
109 ),
110 ),
111 ),
112 );
113 $searchw->sync;
114 # should probably not account backports packages or find a way to search them:
115 my $total_size = keys %$pkgs;
116 my $progresscount;
117
118 my $update_search_pb = sub {
119 $progresscount++;
120 if (!($progresscount % 100)) {
121 $progresscount <= $total_size and $searchprogress->set_fraction($progresscount/$total_size);
122 $searchw->flush; # refresh and handle clicks
123 }
124 };
125 foreach my $medium (grep { !$_->{ignore} } @{$urpm->{media}}) {
126 $searchstop and last;
127 my $gurpm; # per medium download progress bar (if needed)
128 my $_gurpm_clean_guard = before_leaving { undef $gurpm };
129 my $xml_info_file =
130 urpm::media::any_xml_info($urpm, $medium,
131 ($current_search_type eq 'files' ? 'files' : 'info'),
132 undef,
133 sub {
134 $gurpm ||= Rpmdrake::gurpm->new(N("Please wait"),
135 transient => $::main_window);
136 download_callback($gurpm, @_) or do {
137 $searchstop = 1;
138 };
139 });
140 if (!$xml_info_file) {
141 $urpm->{error}(N("no xml-info available for medium \"%s\"", $medium->{name}));
142 next;
143 }
144 $searchstop and last;
145
146 require urpm::xml_info;
147 require urpm::xml_info_pkg;
148
149 $urpm->{log}("getting information from $xml_info_file");
150 if ($current_search_type eq 'files') {
151 # special version for speed (3x faster), hopefully fully compatible
152 my $F = urpm::xml_info::open_lzma($xml_info_file);
153 my $fn;
154 local $_;
155 while (<$F>) {
156 if ($searchstop) {
157 statusbar_msg(N("Search aborted"), 1);
158 goto end_search;
159 }
160 if (m!^<!) {
161 ($fn) = /fn="(.*)"/;
162 $update_search_pb->();
163 } elsif (/$entry_rx/) {
164 $fn or $urpm->{fatal}("fast algorithm is broken, please report a bug");
165 push @search_results, $fn;
166 }
167 }
168 } else {
169 eval {
170 urpm::xml_info::do_something_with_nodes(
171 'info',
172 $xml_info_file,
173 sub {
174 $searchstop and die 'search aborted';
175 my ($node) = @_;
176 $update_search_pb->();
177 push @search_results, $node->{fn} if $node->{description} =~ $entry_rx;
178 #$searchstop and last;
179 return 0 || $searchstop;
180 },
181 );
182 };
183 my $err = $@;
184 if ($err =~ /search aborted/) {
185 statusbar_msg(N("Search aborted"), 1);
186 }
187 }
188 }
189
190 end_search:
191 @search_results = uniq(@search_results); #- there can be multiple packages with same version/release for different arch's
192 @search_results = intersection(\@search_results, \@filtered_pkgs);
193 $searchw->destroy;
194 }
195
196 my $iter;
197 if (@search_results) {
198 $elems{$results_ok} = [ map { [ $_, $results_ok ] } sort { uc($a) cmp uc($b) } @search_results ];
199 $iter = $options->{add_parent}->($results_ok);
200 $options->{add_nodes}->(map { [ $_, $results_ok . ($options->{tree_mode} eq 'by_presence'
201 ? '|' . ($pkgs->{$_}{pkg}->flag_installed ? N("Upgradable") : N("Addable"))
202 : ($options->{tree_mode} eq 'by_selection'
203 ? '|' . ($pkgs->{$_}{selected} ? N("Selected") : N("Not selected"))
204 : ''))
205 ] } sort { uc($a) cmp uc($b) } @search_results);
206 } else {
207 $iter = $options->{add_parent}->($results_none);
208 # clear package list:
209 $options->{add_nodes}->();
210 my $string = $default_list_mode eq 'all' && $filter->[0] eq 'all' ? N("No search results.") :
211 N("No search results. You may want to switch to the '%s' view and to the '%s' filter",
212 N("All"), N("All"),);
213 statusbar_msg($string , 1);
214 gtkset_mousecursor_normal($::w->{rwindow}->window);
215 }
216 my $tree_selection = $tree->get_selection;
217 if (my $path = $tree_model->get_path($iter)) {
218 $tree_selection->select_path($path);
219 $tree->scroll_to_cell($path, undef, 1, 0.5, 0);
220 $tree_selection->signal_emit('changed');
221 }
222 }
223
224 sub quit() {
225 ($rpmdrake_width->[0], $rpmdrake_height->[0]) = $::w->{real_window}->get_size();
226 real_quit();
227 }
228
229 sub run_treeview_dialog {
230 my ($callback_action) = @_;
231
232 my ($options, $tree, $tree_model, $detail_list, $detail_list_model);
233 (undef, $size_free) = MDK::Common::System::df('/usr');
234
235 $::main_window = $w->{real_window};
236
237 $options = {
238 build_tree => sub { build_tree($tree, $tree_model, \%elems, $options, $force_rebuild, @_) },
239 partialsel_unsel => sub {
240 my ($unsel, $sel) = @_;
241 @$sel = grep { exists $pkgs->{$_} } @$sel;
242 @$unsel < @$sel;
243 },
244 get_status => sub {
245 N("Selected: %s / Free disk space: %s", formatXiB($size_selected), formatXiB($size_free*1024));
246 },
247 rebuild_tree => sub {},
248 };
249
250 $tree_model = Gtk2::TreeStore->new("Glib::String", "Glib::String", "Gtk2::Gdk::Pixbuf");
251 $tree_model->set_sort_column_id($grp_columns{label}, 'ascending');
252 $tree = Gtk2::TreeView->new_with_model($tree_model);
253 $tree->get_selection->set_mode('browse');
254
255 $tree->append_column(Gtk2::TreeViewColumn->new_with_attributes(undef, Gtk2::MDV::CellRendererPixWithLabel->new, 'pixbuf' => $grp_columns{icon}, label => $grp_columns{label}));
256 $tree->set_headers_visible(0);
257
258 $detail_list_model = Gtk2::ListStore->new("Glib::String",
259 "Gtk2::Gdk::Pixbuf",
260 "Glib::String",
261 "Glib::Boolean",
262 "Glib::String",
263 "Glib::String",
264 "Glib::String",
265 "Glib::String",
266 "Glib::Boolean");
267
268 $detail_list = Gtk2::TreeView->new_with_model($detail_list_model);
269 $detail_list->append_column(
270 my $col_sel = Gtk2::TreeViewColumn->new_with_attributes(
271 undef,
272 Gtk2::CellRendererToggle->new,
273 active => $pkg_columns{selected},
274 activatable => $pkg_columns{selectable}
275 ));
276 $col_sel->set_fixed_width(34); # w/o this the toggle cells are not displayed
277 $col_sel->set_sizing('fixed');
278 $col_sel->set_sort_column_id($pkg_columns{selected});
279
280 my $display_arch_col = to_bool(arch() =~ /64/);
281 my @columns = (qw(name version release), if_($display_arch_col, 'arch'));
282
283 my %columns = (
284 'name' => {
285 title => N("Package"),
286 markup => $pkg_columns{short_name},
287 },
288 'version' => {
289 title => N("Version"),
290 text => $pkg_columns{version},
291 },
292 'release' => {
293 title => N("Release"),
294 text => $pkg_columns{release},
295 },
296 if_($display_arch_col, 'arch' => {
297 title =>
298 #-PO: "Architecture" but to be kept *small* !!!
299 N("Arch."),
300 text => $pkg_columns{arch},
301 }),
302 );
303 foreach my $col (@columns{@columns}) {
304 $detail_list->append_column(
305 $col->{widget} =
306 Gtk2::TreeViewColumn->new_with_attributes(
307 ' ' . $col->{title} . ' ',
308 $col->{renderer} = Gtk2::CellRendererText->new,
309 ($col->{markup} ? (markup => $col->{markup}) : (text => $col->{text})),
310 )
311 );
312 $col->{widget}->set_sort_column_id($col->{markup} || $col->{text});
313 }
314 $columns{$_}{widget}->set_sizing('autosize') foreach @columns;
315 $columns{name}{widget}->set_property('expand', '1');
316 $columns{name}{renderer}->set_property('ellipsize', 'end');
317 $columns{$_}{renderer}->set_property('xpad', '6') foreach @columns;
318 $columns{name}{widget}->set_resizable(1);
319 #$detail_list_model->set_sort_column_id($pkg_columns{text}, 'ascending');
320 $detail_list_model->set_sort_func($pkg_columns{version}, \&sort_callback);
321 $detail_list->set_rules_hint(1);
322
323 $detail_list->append_column(
324 my $pixcolumn =
325 Gtk2::TreeViewColumn->new_with_attributes(
326 #-PO: "Status" should be kept *small* !!!
327 N("Status"),
328 my $rdr = Gtk2::CellRendererPixbuf->new,
329 'pixbuf' => $pkg_columns{state_icon})
330 );
331 $rdr->set_fixed_size(34, 24);
332 $pixcolumn->set_sort_column_id($pkg_columns{state});
333
334 compute_main_window_size($w);
335
336 my $cursor_to_restore;
337 $_->signal_connect(
338 expose_event => sub {
339 $cursor_to_restore or return;
340 gtkset_mousecursor_normal($tree->window);
341 undef $cursor_to_restore;
342 },
343 ) foreach $tree, $detail_list;
344 $tree->get_selection->signal_connect(changed => sub {
345 my ($model, $iter) = $_[0]->get_selected;
346 return if !$iter;
347 state $current_group;
348 my $new_group = $model->get_path_str($iter);
349 return if $current_group eq $new_group && !$force_displaying_group;
350 undef $force_displaying_group;
351 $current_group = $new_group;
352 $model && $iter or return;
353 my $group = $model->get($iter, 0);
354 my $parent = $iter;
355 while ($parent = $model->iter_parent($parent)) {
356 $group = join('|', $model->get($parent, 0), $group);
357 }
358 $detail_list->window->freeze_updates;
359 $options->{add_nodes}->(@{$elems{$group}});
360 $detail_list->window->thaw_updates if $detail_list->window;
361 });
362
363 $options->{state}{splited} = 1;
364 $options->{state}{flat} = $tree_flat->[0];
365
366 my $is_backports = get_inactive_backport_media(fast_open_urpmi_db());
367
368 my %filters = (all => N("All"),
369 installed => N("Installed"),
370 non_installed => N("Not installed"),
371 );
372
373 my %rfilters = reverse %filters;
374
375
376 # handle migrating config file from rpmdrake <= 4.9
377 if (exists $filters{$default_list_mode}) {
378 $filter->[0] = $default_list_mode;
379 $default_list_mode = 'all';
380 }
381
382 $options->{tree_mode} = $default_list_mode;
383
384 my %modes = (
385 flat => N("All packages, alphabetical"),
386 by_group => N("All packages, by group"),
387 by_leaves => N("Leaves only, sorted by install date"),
388 by_presence => N("All packages, by update availability"),
389 by_selection => N("All packages, by selection state"),
390 by_size => N("All packages, by size"),
391 by_source => N("All packages, by medium repository"),
392 );
393
394
395 my %views = (all => N("All"),
396 if_($is_backports, backports =>
397 #-PO: Backports media are newer but less-tested versions of some packages in main
398 #-PO: See http://wiki.mandriva.com/en/Policies/SoftwareMedia#.2Fmain.2Fbackports
399 N("Backports")),
400 meta_pkgs => N("Meta packages"),
401 gui_pkgs => N("Packages with GUI"),
402 all_updates => N("All updates"),
403 security => N("Security updates"),
404 bugfix => N("Bugfixes updates"),
405 normal => N("General updates")
406 );
407 my %rviews = reverse %views;
408 $options->{rviews} = \%rviews;
409
410 my %default_mode = (install => 'all', # we want the new GUI by default instead of "non_installed"
411 remove => 'installed',
412 update => 'security',
413 );
414 my %wanted_categories = (
415 all_updates => [ qw(security bugfix normal) ],
416 security => [ 'security' ],
417 bugfix => [ 'bugfix' ],
418 normal => [ 'normal' ],
419 );
420 my $old_value;
421 my $view_box = gtknew(
422 'ComboBox',
423 list => [
424 qw(all meta_pkgs gui_pkgs all_updates security bugfix normal),
425 if_($is_backports, 'backports')
426 ],
427 format => sub { $views{$_[0]} }, text => $views{$default_list_mode},
428 tip => N("View"),
429 changed => sub {
430 my $val = $_[0]->get_text;
431 return if $val eq $old_value; # workarounding gtk+ sending us sometimes twice events
432 $old_value = $val;
433 $default_list_mode = $rviews{$val};
434 if (my @cat = $wanted_categories{$rviews{$val}} && @{$wanted_categories{$rviews{$val}}}) {
435 @$mandrakeupdate_wanted_categories = @cat;
436 }
437
438 if ($options->{tree_mode} ne $val) {
439 $tree_mode->[0] = $options->{tree_mode} = $rviews{$val};
440 $tree_flat->[0] = $options->{state}{flat};
441 reset_search();
442 switch_pkg_list_mode($rviews{$val});
443 $options->{rebuild_tree}->();
444 }
445 }
446 );
447
448 $options->{tree_submode} ||= $default_list_mode;
449 $options->{tree_subflat} ||= $options->{state}{flat};
450
451
452 my $filter_box = gtknew(
453 'ComboBox',
454 list => [ qw(all installed non_installed) ], text => $filters{$filter->[0]},
455 format => sub { $filters{$_[0]} },
456 tip => N("Filter"),
457 changed => sub {
458 state $oldval;
459 my $val = $_[0]->get_text;
460 return if $val eq $oldval; # workarounding gtk+ sending us sometimes twice events
461 $oldval = $val;
462 $val = $rfilters{$val};
463 if ($filter->[0] ne $val) {
464 $filter->[0] = $val;
465 reset_search();
466 slow_func($::main_window->window, sub { switch_pkg_list_mode($default_list_mode) });
467 $options->{rebuild_tree}->();
468 }
469 }
470 );
471
472 my $view_callback = sub {
473 my ($val) = @_;
474 return if $val eq $old_value; # workarounding gtk+ sending us sometimes twice events
475 $old_value = $val;
476 return if $mode->[0] eq $val;
477 $mode->[0] = $val;
478 $tree_flat->[0] = $options->{state}{flat} = member($mode->[0], qw(flat by_leaves by_selection by_size));
479
480 if ($options->{tree_mode} ne $val) {
481 reset_search();
482 $options->{rebuild_tree}->();
483 }
484 };
485
486
487 my @search_types = qw(normal descriptions summaries files);
488 my $current_search_type = $search_types[0];
489 my $search_menu = Gtk2::Menu->new;
490 my $i = 0;
491 my $previous;
492 foreach (N("in names"), N("in descriptions"), N("in summaries"), N("in file names")) {
493 my ($name, $val) = ($_, $i);
494 $search_menu->append(gtksignal_connect(gtkshow(
495 $previous = Gtk2::RadioMenuItem->new_with_label($previous, $name)),
496 activate => sub { $current_search_type = $search_types[$val] }));
497 $i++;
498 }
499
500 my $info = Gtk2::Mdv::TextView->new;
501 $info->set_left_margin(2);
502 $info->set_right_margin(15); #- workaround when right elevator of scrolled window appears
503
504 my $find_callback = sub {
505 do_search($find_entry, $tree, $tree_model, $options, $current_search_type, $urpm, $pkgs);
506 };
507
508 my $hpaned = gtknew('HPaned', position => $typical_width*0.9,
509 child1 => gtknew('ScrolledWindow', child => $tree),
510 resize1 => 0, shrink1 => 0,
511 resize2 => 1, shrink2 => 0,
512 child2 => gtknew('VPaned',
513 child1 => gtknew('ScrolledWindow', child => $detail_list), resize1 => 1, shrink1 => 0,
514 child2 => gtknew('ScrolledWindow', child => $info), resize2 => 1, shrink2 => 0
515 )
516 );
517
518 my $reload_db_and_clear_all = sub {
519 slow_func($w->{real_window}->window, sub {
520 $force_rebuild = 1;
521 pkgs_provider({ skip_updating_mu => 1 }, $options->{tree_mode});
522 reset_search();
523 $size_selected = 0;
524 $options->{rebuild_tree}->();
525 $find_callback->();
526 });
527 };
528
529 my $status = gtknew('Label');
530 my $checkbox_show_autoselect;
531 my %check_boxes;
532 my $auto_select_string =
533 N("/_Options") . N("/_Select dependencies without asking");
534 my $clean_cache_string =
535 N("/_Options") . "/" .
536 N("Clear download cache after successful install");
537 my $updates_string = N("/_Options") . N("/_Compute updates on startup");
538 my $NVR_string = N("/_Options") . "/" . N("Search in _full package names");
539 my $regexp_search_string = N("/_Options") . "/" . N("Use _regular expressions in searches");
540 my ($menu, $factory) = create_factory_menu(
541 $w->{real_window},
542 [ N("/_File"), undef, undef, undef, '<Branch>' ],
543 if_(
544 ! $>,
545 [ N("/_File") . N("/_Update media"), undef, sub {
546 update_sources_interactive($urpm, transient => $w->{real_window})
547 and $reload_db_and_clear_all->();
548 }, undef, '<Item>' ]
549 ),
550 [ N("/_File") . N("/_Reset the selection"), undef, sub {
551 if ($MODE ne 'remove') {
552 $urpm->disable_selected(
553 open_rpm_db(), $urpm->{state},
554 map { if_($pkgs->{$_}{selected}, $pkgs->{$_}{pkg}) } keys %$pkgs,
555 );
556 }
557 $pkgs->{$_}{selected} = 0 foreach keys %$pkgs;
558 reset_search();
559 $size_selected = 0;
560 $force_displaying_group = 1;
561 my $tree_selection = $tree->get_selection;
562 $tree_selection->select_path(Gtk2::TreePath->new_from_string('0')) if !$tree_selection->get_selected;
563 $tree_selection->signal_emit('changed');
564 }, undef, '<Item>' ],
565 [ N("/_File") . N("/Reload the _packages list"), undef, $reload_db_and_clear_all, undef, '<Item>' ],
566 [ N("/_File") . N("/_Quit"), N("<control>Q"), \&quit, undef, '<Item>', ],
567 #[ N("/_View"), undef, undef, undef, '<Branch>' ],
568 if_(!$>,
569 [ N("/_Options"), undef, undef, undef, '<Branch>' ],
570 [ $auto_select_string, undef,
571 sub {
572 my $box = $check_boxes{$auto_select_string};
573 $auto_select->[0] = $box->get_active;
574 $::rpmdrake_options{auto} = $box->get_active;
575 $urpm->{options}{auto} = $box->get_active;
576 },
577 undef, '<CheckItem>' ],
578 [ $clean_cache_string, undef,
579 sub {
580 $clean_cache->[0] =
581 $check_boxes{$clean_cache_string}->get_active;
582 $::noclean = !$clean_cache->[0];
583 },
584 undef, '<CheckItem>' ],
585 [ N("/_Options") . N("/_Media Manager"), undef, sub {
586 require Rpmdrake::edit_urpm_sources;
587 Rpmdrake::edit_urpm_sources::run() && $reload_db_and_clear_all->();
588 }, undef, '<Item>' ],
589 [ N("/_Options") . N("/_Show automatically selected packages"), undef, sub {
590 $dont_show_selections->[0] = !$checkbox_show_autoselect->get_active;
591 }, undef, '<CheckItem>' ],
592
593 [ $updates_string, undef, sub {
594 $compute_updates->[0] = $check_boxes{$updates_string}->get_active;
595 }, undef, '<CheckItem>' ],
596 [ $NVR_string, undef, sub {
597 $NVR_searches->[0] = $check_boxes{$NVR_string}->get_active;
598 }, undef, '<CheckItem>' ],
599 [ $regexp_search_string, undef, sub {
600 $use_regexp->[0] = $check_boxes{$regexp_search_string}->get_active;
601 }, undef, '<CheckItem>' ],
602 ),
603 [ N("/_View"), undef, undef, undef, '<Branch>' ],
604 (map {
605 state ($idx, $previous);
606 my $type = $idx ? join('/', N("/_View"), $previous) : '<RadioItem>';
607 $type =~ s/_//g; # gtk+ retrieve widgets by their path w/o any shortcut marks
608 $previous = $modes{$_};
609 $idx++;
610 my $val = $_;
611 [ N("/_View") . '/' . $modes{$_}, undef, sub { $view_callback->($val) }, 0, $type ];
612 } qw(flat by_group by_leaves by_presence by_selection by_size by_source)),
613 [ N("/_Help"), undef, undef, undef, '<Branch>' ],
614 [ N("/_Help") . N("/_Report Bug"), undef, sub { run_drakbug('rpmdrake') }, undef, '<Item>' ],
615 [ N("/_Help") . N("/_Help"), undef, sub { rpmdrake::open_help('') }, undef, '<Item>' ],
616 [ N("/_Help") . N("/_About..."), undef, sub {
617 my $license = formatAlaTeX(translate($::license));
618 $license =~ s/\n/\n\n/sg; # nicer formatting
619 my $w = gtknew('AboutDialog', name => N("Rpmdrake"),
620 version => $Rpmdrake::init::version,
621 copyright => N("Copyright (C) %s by Mandriva", '2002-2009'),
622 license => $license, wrap_license => 1,
623 comments => N("Rpmdrake is Mageia package management tool."),
624 website => 'http://www.mageia.org',
625 website_label => N("Mageia"),
626 authors => 'Thierry Vignaud <vignaud@mandriva.com>',
627 artists => 'Hélène Durosini <ln@mandriva.com>',
628 translator_credits =>
629 #-PO: put here name(s) and email(s) of translator(s) (eg: "John Smith <jsmith@nowhere.com>")
630 N("_: Translator(s) name(s) & email(s)\n"),
631 transient_for => $::main_window, modal => 1, position_policy => 'center-on-parent',
632 );
633 $w->show_all;
634 $w->run;
635 }, undef, '<Item>'
636 ]
637
638 );
639
640 # to retrieve a path, one must prevent "accelerators completion":
641 my $get_path = sub { return join('', map { my $i = $_; $i =~ s/_//g; $i } @_) };
642
643 if (my $widget = $factory->get_item('<main>' . $get_path->(N("/_View") . '/' . $modes{$mode->[0]}))) {
644 $widget->set_active(1);
645 } else {
646 warn "Impossible to set $mode->[0] view as default\n";
647 }
648
649 %check_boxes = map {
650 $_ => $factory->get_widget("<main>" . $get_path->($_));
651 } ($auto_select_string,
652 $clean_cache_string,
653 $NVR_string,
654 $updates_string,
655 $regexp_search_string);
656
657 if (!$>) {
658 $check_boxes{$regexp_search_string}->set_active($use_regexp->[0]);
659 $check_boxes{$NVR_string}->set_active($NVR_searches->[0]);
660 $check_boxes{$auto_select_string}->set_active($auto_select->[0]);
661 $check_boxes{$updates_string}->set_active($compute_updates->[0]);
662 $check_boxes{$clean_cache_string}->set_active($clean_cache->[0]);
663 }
664
665 $checkbox_show_autoselect = $factory->get_widget("<main>" . strip_first_underscore(N("/_Options"), N("/_Show automatically selected packages")))
666 and $checkbox_show_autoselect->set_active(!$dont_show_selections->[0]);
667
668 my $accel = Gtk2::AccelGroup->new;
669 $accel->connect(Gtk2::Gdk->keyval_from_name('F'), ['control-mask'], ['visible'], sub { $find_entry->grab_focus() });
670 $w->{real_window}->add_accel_group($accel);
671
672 gtkadd(
673 $w->{window},
674 gtkpack_(
675 gtknew('VBox', spacing => 3),
676 0, $menu,
677 if_(second(gtkroot()->get_size()) >= 600, 0, getbanner()),
678 1, gtkadd(
679 gtknew('Frame', border_width => 3, shadow_type => 'none'),
680 gtkpack_(
681 gtknew('VBox', spacing => 3),
682 0, gtkpack_(
683 gtknew('HBox', spacing => 10),
684 0, $view_box,
685 0, $filter_box,
686 0, gtknew('Label', text => N("Find:")),
687 1, $find_entry = gtknew('Entry', width => 260,
688 primary_icon => 'gtk-find',
689 secondary_icon => 'gtk-clear',
690 tip => N("Please type in the string you want to search then press the <enter> key"),
691 'icon-release' => $find_callback,
692 'icon-press' => sub {
693 my (undef, $pos, $event) = @_;
694 # emulate Sexy::IconEntry's clear_button:
695 if ($pos eq 'secondary') {
696 $find_entry->set_text('');
697 reset_search();
698 }
699 return if $pos ne 'primary';
700 $search_menu->popup(undef, undef, undef, undef, $event->button, $event->time);
701 },
702 key_press_event => sub {
703 member($_[1]->keyval, $Gtk2::Gdk::Keysyms{Return}, $Gtk2::Gdk::Keysyms{KP_Enter})
704 and $find_callback->();
705 },
706 ),
707 ),
708 1, $hpaned,
709 0, $status,
710 0, gtkpack_(
711 gtknew('HBox', spacing => 20),
712 0, gtksignal_connect(
713 Gtk2::Button->new(but_(N("Select all"))),
714 clicked => sub {
715 toggle_all($options, 1);
716 },
717 ),
718 1, gtknew('Label'),
719 0, my $action_button = gtksignal_connect(
720 Gtk2::Button->new(but_(N("Apply"))),
721 clicked => sub { do_action($options, $callback_action, $info) },
722 ),
723 0, gtksignal_connect(
724 Gtk2::Button->new(but_(N("Quit"))),
725 clicked => \&quit,
726 ),
727 ),
728 ),
729 ),
730 0, $statusbar = Gtk2::Statusbar->new,
731 ),
732 );
733 $action_button->set_sensitive(0) if $>;
734 $find_entry->grab_focus;
735
736 gtktext_insert($info, [
737 [ $info->render_icon('gtk-dialog-info', 'GTK_ICON_SIZE_DIALOG', undef) ],
738 @{ ugtk2::markup_to_TextView_format(
739 formatAlaTeX(join("\n\n\n", format_header(N("Quick Introduction")),
740 N("You can browse the packages through the categories tree on the left."),
741 N("You can view information about a package by clicking on it on the right list."),
742 N("To install, update or remove a package, just click on its \"checkbox\"."))))
743 }
744 ]);
745
746 $w->{rwindow}->set_default_size($typical_width*2.7, 500) if !$::isEmbedded;
747 $find_entry->set_text($rpmdrake_options{search}[0]) if $rpmdrake_options{search};
748
749 if ($rpmdrake_width->[0] && $rpmdrake_height->[0]) {
750 # so that we can shrink back:
751 $w->{real_window}->set_default_size($rpmdrake_width->[0], $rpmdrake_height->[0]);
752 }
753 $w->{rwindow}->show_all;
754 $w->{rwindow}->set_sensitive(0);
755
756 # ensure treeview get realized so that ->get_selection returns something
757 $detail_list->realize;
758 gtkflush();
759
760 slow_func($::main_window->window, sub { pkgs_provider({}, $default_list_mode) }); # default mode
761 if (@initial_selection) {
762 $options->{initial_selection} = \@initial_selection;
763 $pkgs->{$_}{selected} = 0 foreach @initial_selection;
764 }
765
766 $w->{rwindow}->set_sensitive(1);
767
768 $options->{widgets} = {
769 w => $w,
770 tree => $tree,
771 tree_model => $tree_model,
772 detail_list_model => $detail_list_model,
773 detail_list => $detail_list,
774 info => $info,
775 status => $status,
776 };
777 $options->{init_callback} = $find_callback if $rpmdrake_options{search};
778
779 ask_browse_tree_given_widgets_for_rpmdrake($options);
780 }
781
782
783 # -=-=-=---=-=-=---=-=-=-- main -=-=-=---=-=-=---=-=-=-
784
785
786 if (my $pid = is_running('rpmdrake')) {
787 interactive_msg(N("Warning"), N("rpmdrake is already running (pid: %s)", $pid), yesno => [ N("Quit") ]);
788 exit(0);
789 }
790
791 $w = ugtk2->new(N("Software Management"));
792 $w->{rwindow}->show_all if $::isEmbedded;
793
794 readconf();
795
796 warn_about_user_mode();
797
798 do_merge_if_needed();
799
800
801 init();
802
803 run_treeview_dialog(\&perform_installation);
804
805 writeconf();
806
807 myexit(0);

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.30