summaryrefslogtreecommitdiffstats
path: root/perl-install/diskdrake/hd_gtk.pm
diff options
context:
space:
mode:
Diffstat (limited to 'perl-install/diskdrake/hd_gtk.pm')
-rw-r--r--perl-install/diskdrake/hd_gtk.pm416
1 files changed, 275 insertions, 141 deletions
diff --git a/perl-install/diskdrake/hd_gtk.pm b/perl-install/diskdrake/hd_gtk.pm
index d437799c5..ed3955ea7 100644
--- a/perl-install/diskdrake/hd_gtk.pm
+++ b/perl-install/diskdrake/hd_gtk.pm
@@ -1,36 +1,34 @@
-package diskdrake::hd_gtk; # $Id$
+package diskdrake::hd_gtk;
use diagnostics;
use strict;
use common;
-use resize_fat::main;
-use my_gtk qw(:helpers :wrappers :ask);
-use partition_table qw(:types);
-use partition_table::raw;
+use mygtk3 qw(gtknew);
+use ugtk3 qw(:helpers :wrappers :create);
+use partition_table;
+use fs::type;
use detect_devices;
use diskdrake::interactive;
use run_program;
-use loopback;
use devices;
-use raid;
-use any;
use log;
use fsedit;
-use fs;
+use feature qw(state);
-my ($width, $height, $minwidth) = (400, 50, 5);
-my ($all_hds, $in, $current_kind, $current_entry, $update_all);
+my ($width, $height, $minwidth) = (400, 50, 16);
+my ($all_hds, $in, $do_force_reload, $current_kind, $current_entry, $update_all);
my ($w, @notebook, $done_button);
-=begin
-struct {
+=head1 SYNOPSYS
+
+ struct {
string name # which is displayed in tab of the notebook
bool no_auto # wether the kind can disappear after creation
- string type # one of { 'hd', 'raid', 'lvm', 'loopback', 'removable', 'nfs', 'smb' }
- hd | hd_lvm | part_raid[] | part_loopback[] | raw_hd[] val
-
+ string type # one of { 'hd', 'raid', 'lvm', 'loopback', 'removable', 'nfs', 'smb', 'dmcrypt' }
+ hd | hd_lvm | part_raid[] | part_dmcrypt[] | part_loopback[] | raw_hd[] val
+
#
widget main_box
widget display_box
@@ -38,64 +36,105 @@ struct {
widget info_box
} current_kind
-part current_entry
+ part current_entry
-notebook current_kind[]
+ notebook current_kind[]
=cut
+sub load_theme() {
+ my $css = "/usr/share/libDrakX/diskdrake.css";
+ -r $css or $css = dirname(__FILE__) . "/../diskdrake.css";
+ -r $css or $css = dirname(__FILE__) . "/../share/diskdrake.css";
+ my $pl = Gtk3::CssProvider->new;
+ $pl->load_from_path($css);
+ Gtk3::StyleContext::add_provider_for_screen(Gtk3::Gdk::Screen::get_default(), $pl, Gtk3::STYLE_PROVIDER_PRIORITY_APPLICATION);
+}
+
sub main {
- ($in, $all_hds, my $nowizard) = @_;
+ ($in, $all_hds, $do_force_reload) = @_;
@notebook = ();
local $in->{grab} = 1;
- $w = my_gtk->new('DiskDrake');
- my $rc = "/usr/share/libDrakX/diskdrake.rc";
- -r $rc or $rc = dirname(__FILE__) . "/../diskdrake.rc";
- -r $rc or $rc = dirname(__FILE__) . "/../share/diskdrake.rc";
- Gtk::Rc->parse($rc);
+ $w = ugtk3->new(N("Partitioning"));
+ mygtk3::register_main_window($w->{real_window}) if !$::isEmbedded && !$::isInstall;
+
+ load_theme();
+ $w->{window}->signal_connect('style-updated' => \&load_theme);
# TODO
# is_empty_array_ref($all_hds->{raids}) or raid::stopAll;
# updateLoopback();
gtkadd($w->{window},
- gtkpack_(new Gtk::VBox(0,7),
- 0, (my $filesystems_button_box = filesystems_button_box()),
- 1, (my $notebook_widget = new Gtk::Notebook),
- 0, (my $per_kind_action_box = new Gtk::HBox(0,0)),
- 0, (my $general_action_box = new Gtk::HBox(0,0)),
+ gtkpack_(Gtk3::VBox->new(0,7),
+ 0, gtknew(($::isInstall ? ('Title1', 'label') : ('Label_Left', 'text'))
+ => N("Click on a partition, choose a filesystem type then choose an action"),
+ # workaround infamous 6 years old gnome bug #101968:
+ width => mygtk3::get_label_width()
+ ),
+ 1, (my $notebook_widget = Gtk3::Notebook->new),
+ 0, (my $per_kind_action_box = gtknew('HButtonBox', layout => 'edge')),
+ 0, Gtk3::HSeparator->new,
+ 0, (my $general_action_box = gtknew('HBox', spacing => 5)),
),
);
- my $lock;
+ my ($lock, $initializing) = (undef, 1);
$update_all = sub {
+ my ($o_refresh_gui) = @_;
+ state $not_first;
+ return if $initializing && $not_first;
+ $not_first = 1;
$lock and return;
$lock = 1;
- partition_table::assign_device_numbers($_) foreach fsedit::all_hds($all_hds);
+ partition_table::assign_device_numbers($_) foreach fs::get::hds($all_hds);
create_automatic_notebooks($notebook_widget);
- general_action_box($general_action_box, $nowizard);
+ general_action_box($general_action_box);
per_kind_action_box($per_kind_action_box, $current_kind);
current_kind_changed($in, $current_kind);
current_entry_changed($current_kind, $current_entry);
$lock = 0;
+ if ($o_refresh_gui) {
+ my $new_page = $o_refresh_gui > 1 ? $notebook_widget->get_current_page : 0;
+ $notebook_widget->set_current_page(-1);
+ $notebook_widget->set_current_page($new_page);
+ }
};
create_automatic_notebooks($notebook_widget);
- $notebook_widget->signal_connect('switch_page' => sub {
+ $notebook_widget->signal_connect(switch_page => sub {
$current_kind = $notebook[$_[2]];
$current_entry = '';
$update_all->();
});
+ # ensure partitions bar is properly sized on first display:
+ $notebook_widget->signal_connect(realize => $update_all);
$w->sync;
+ # add a bogus tab so that gtk+ displayed everything when there's only one disk:
+ $notebook_widget->prepend_page(Gtk3::Label->new, Gtk3::Label->new);
+ $notebook_widget->set_current_page(0);
+ # there's always at least one child (at least a button for create a new part on empty discs):
+ my @children = $current_kind->{display_box} ? $current_kind->{display_box}->get_children : ();
+ # workaround for $notebook_widget being realized too early:
+ if (!@children ||!$done_button) {
+ $notebook_widget->set_current_page(-1);
+ $notebook_widget->set_current_page(0);
+ undef $initializing;
+ $update_all->(2);
+ }
+ undef $initializing;
+ # remove bogus tab we added just to be sure gtk+ displayed everything:
+ $notebook_widget->remove_page(0);
+ # restore position when there's several disks:
+ $notebook_widget->set_current_page(0);
$done_button->grab_focus;
- $my_gtk::pop_it = 1;
- $in->ask_okcancel(_("Read carefully!"), _("Please make a backup of your data first"), 1) or return
- if $::isStandalone;
- $in->ask_warn('',
-_("If you plan to use aboot, be carefull to leave a free space (2048 sectors is enough)
-at the beginning of the disk")) if (arch() eq 'alpha') and !$::isEmbedded;
+ if (!$::testing) {
+ $in->ask_from_list_(N("Read carefully"), N("Please make a backup of your data first"),
+ [ N_("Exit"), N_("Continue") ], N_("Continue")) eq N_("Continue") or return
+ if $::isStandalone;
+ }
$w->main;
}
@@ -103,25 +142,38 @@ at the beginning of the disk")) if (arch() eq 'alpha') and !$::isEmbedded;
sub try {
my ($name, @args) = @_;
my $f = $diskdrake::interactive::{$name} or die "unknown function $name";
- try_($name, \&{$f}, @args);
+ try_($name, \&$f, @args);
}
sub try_ {
my ($name, $f, @args) = @_;
- fsedit::undo_prepare($all_hds) if $name ne 'Undo';
-
+ my $dm_active_before = ($current_entry && $current_entry->{dm_active} && $current_entry->{dm_name});
my $v = eval { $f->($in, @args, $all_hds) };
if (my $err = $@) {
- $err =~ /setstep/ and die '';
- $in->ask_warn(_("Error"), formatError($err));
+ warn $err, "\n", backtrace() if $in->isa('interactive::gtk');
+ $in->ask_warn(N("Error"), formatError($err));
+ }
+ my $refresh = 0;
+ if ($v eq 'force_reload') {
+ $all_hds = $do_force_reload->();
+ $refresh = 1;
}
- $current_entry = '' if !diskdrake::interactive::is_part_existing($current_entry, $all_hds);
- $update_all->();
-
- if ($v && member($name, 'Done', 'Wizard')) {
- $::isEmbedded ? kill('USR1', $::CCPID) : Gtk->main_quit;
+ if (!diskdrake::interactive::is_part_existing($current_entry, $all_hds)) {
+ $current_entry = '';
+ } elsif (!$dm_active_before && $current_entry->{dm_active} && $current_entry->{dm_name}) {
+ if (my $mapped_part = fs::get::device2part("mapper/$current_entry->{dm_name}", $all_hds->{dmcrypts})) {
+ $current_entry = $mapped_part;
+ $refresh = 2;
+ }
}
+ $update_all->($refresh);
+
+ Gtk3->main_quit if $v && member($name, 'Done');
+}
+
+sub get_action_box_size() {
+ $::isStandalone ? 200 : 150, $::isEmbedded ? 150 : 180;
}
################################################################################
@@ -131,91 +183,108 @@ sub add_kind2notebook {
my ($notebook_widget, $kind) = @_;
die if $kind->{main_box};
- $kind->{display_box} = gtkset_usize(new Gtk::HBox(0,0), $width, $height);
- $kind->{action_box} = gtkset_usize(new Gtk::VBox(0,0), 150, 180);
- $kind->{info_box} = new Gtk::VBox(0,0);
- $kind->{main_box} =
- gtkpack_(new Gtk::VBox(0,7),
- 0, $kind->{display_box},
- 1, gtkpack_(new Gtk::HBox(0,7),
- 0, $kind->{action_box},
- 1, $kind->{info_box}));
- my_gtk::add2notebook($notebook_widget, $kind->{name}, $kind->{main_box});
+ $kind->{display_box} = gtkset_size_request(Gtk3::HBox->new(0,0), $width, $height);
+ $kind->{action_box} = gtkset_size_request(Gtk3::VBox->new, get_action_box_size());
+ $kind->{info_box} = Gtk3::VBox->new(0,0);
+ my $box =
+ gtkpack_(Gtk3::VBox->new(0,7),
+ 0, create_scrolled_window($kind->{display_box}, [ 'automatic', 'never' ]),
+ 0, filesystems_button_box(),
+ 1, $kind->{info_box});
+ $kind->{main_box} = gtknew('HBox', spacing => 5, children => [
+ 1, $box,
+ 0, $kind->{action_box},
+ ]);
+ ugtk3::add2notebook($notebook_widget, $kind->{name}, $kind->{main_box});
push @notebook, $kind;
$kind;
}
+sub interactive_help() {
+ if ($::isInstall) {
+ $in->display_help({ interactive_help_id => 'diskdrake' });
+ } else {
+ require run_program;
+ run_program::raw({ detach => 1 }, 'drakhelp', '--id', 'diskdrake');
+ }
+}
+
sub general_action_box {
- my ($box, $nowizard) = @_;
- $_->widget->destroy foreach $box->children;
- my @actions = (if_($::isInstall && !$nowizard, __("Wizard")),
+ my ($box) = @_;
+ $_->destroy foreach $box->get_children;
+
+ my $box_start = gtknew('HButtonBox', layout => 'start', children_tight => [
+ gtknew('Install_Button', text => N("Help"), clicked => \&interactive_help)
+ ]);
+
+ my @actions = (
diskdrake::interactive::general_possible_actions($in, $all_hds),
- __("Done"));
+ N_("Done"));
+ my $box_end = gtknew('HButtonBox', layout => 'end', spacing => 5);
foreach my $s (@actions) {
- my $button = new Gtk::Button(translate($s));
+ my $button = Gtk3::Button->new(translate($s));
$done_button = $button if $s eq 'Done';
- gtkadd($box, gtksignal_connect($button, clicked => sub { try($s) }));
+ gtkadd($box_end, gtksignal_connect($button, clicked => sub { try($s) }));
}
+ gtkadd($box, $box_start, $box_end);
}
sub per_kind_action_box {
my ($box, $kind) = @_;
- $_->widget->destroy foreach $box->children;
-
- $kind->{type} =~ /hd|lvm/ or return;
+ $_->destroy foreach $box->get_children;
- foreach my $s (diskdrake::interactive::hd_possible_actions($in, kind2hd($kind), $all_hds)) {
+ my @actions = (if_($kind->{type} =~ /hd|lvm/, diskdrake::interactive::hd_possible_actions_base($in)),
+ diskdrake::interactive::hd_possible_actions_extra($in));
+ foreach my $s (@actions) {
gtkadd($box,
- gtksignal_connect(new Gtk::Button(translate($s)),
+ gtksignal_connect(Gtk3::Button->new(translate($s)),
clicked => sub { try($s, kind2hd($kind)) }));
}
+ # make sure a big translations window to resize (as by default all buttons have the same size):
+ $box->set_child_non_homogeneous($_, Glib::TRUE), "\n" foreach $box->get_children;
}
sub per_entry_action_box {
my ($box, $kind, $entry) = @_;
- $_->widget->destroy foreach $box->children;
+ $_->destroy foreach $box->get_children;
if ($entry) {
my @buttons = map {
my $s = $_;
- my $w = new Gtk::Button(translate($s));
+ my $w = Gtk3::Button->new(translate($s));
$w->signal_connect(clicked => sub { try($s, kind2hd($kind), $entry) });
$w;
} diskdrake::interactive::part_possible_actions($in, kind2hd($kind), $entry, $all_hds);
- gtkadd($box, gtkadd(new Gtk::Frame(_("Choose action")),
- createScrolledWindow(gtkpack__(new Gtk::VBox(0,0), @buttons)))) if @buttons;
+ gtkadd($box, create_scrolled_window(gtkpack__(Gtk3::VBox->new, @buttons), undef, 'none')) if @buttons;
} else {
- my $txt = !$::isStandalone && fsedit::is_one_big_fat($all_hds->{hds}) ?
-_("You have one big FAT partition
-(generally used by MicroSoft Dos/Windows).
+ my $txt = !$::isStandalone && fsedit::is_one_big_fat_or_NT($all_hds->{hds}) ?
+N("You have one big Microsoft Windows partition.
I suggest you first resize that partition
-(click on it, then click on \"Resize\")") : _("Please click on a partition");
- gtkpack($box, gtktext_insert(new Gtk::Text, $txt));
+(click on it, then click on \"Resize\")") : N("Please click on a partition");
+ gtkpack($box, gtktext_insert(Gtk3::TextView->new, $txt));
}
}
sub per_entry_info_box {
my ($box, $kind, $entry) = @_;
- $_->widget->destroy foreach $box->children;
+ $_->destroy foreach $box->get_children;
my $info;
if ($entry) {
$info = diskdrake::interactive::format_part_info(kind2hd($kind), $entry);
} elsif ($kind->{type} =~ /hd|lvm/) {
$info = diskdrake::interactive::format_hd_info($kind->{val});
}
- gtkpack($box, gtkadd(new Gtk::Frame(_("Details")), gtkset_justify(new Gtk::Label($info), 'left')));
+ gtkpack($box, gtkadd(gtkcreate_frame(N("Details")),
+ gtknew('HBox', border_width => 5, children_loose => [
+ gtkset_alignment(gtkset_justify(gtknew('Label', selectable => 1, text => $info), 'left'), 0, 0) ])));
}
sub current_kind_changed {
- my ($in, $kind) = @_;
-
- $_->widget->destroy foreach $kind->{display_box}->children;
+ my ($_in, $kind) = @_;
- my $v = $kind->{val};
- my @parts =
- $kind->{type} eq 'raid' ? grep { $_ } @$v :
- $kind->{type} eq 'loopback' ? @$v : fsedit::get_fstab_and_holes($v);
- my $totalsectors =
- $kind->{type} =~ /raid|loopback/ ? sum(map { $_->{size} } @parts) : $v->{totalsectors};
+ return if !$kind->{display_box};
+ $_->destroy foreach $kind->{display_box}->get_children;
+ my @parts = kind2parts($kind);
+ my $totalsectors = kind2sectors($kind, @parts);
create_buttons4partitions($kind, $totalsectors, @parts);
}
@@ -230,7 +299,6 @@ sub current_entry_changed {
sub create_automatic_notebooks {
my ($notebook_widget) = @_;
- my @l = fsedit::all_hds($all_hds);
$_->{marked} = 0 foreach @notebook;
my $may_add = sub {
@@ -242,39 +310,71 @@ sub create_automatic_notebooks {
};
$may_add->(hd2kind($_)) foreach @{$all_hds->{hds}};
$may_add->(lvm2kind($_)) foreach @{$all_hds->{lvms}};
- $may_add->(raid2kind()) if grep { $_ } @{$all_hds->{raids}};
+ $may_add->(raid2kind()) if @{$all_hds->{raids}};
$may_add->(loopback2kind()) if @{$all_hds->{loopbacks}};
- @notebook = grep_index {
- my $b = $_->{marked} or $notebook_widget->remove_page($::i);
- $b;
+ my $i = 0;
+ @notebook = grep {
+ if ($_->{marked}) {
+ $i++;
+ 1;
+ } else {
+ $notebook_widget->remove_page($i);
+ 0;
+ }
} @notebook;
- @notebook or die '';
+ @notebook or $in->ask_warn(N("Error"), N("No hard disk drives found")), $in->exit(1);
}
################################################################################
# parts: helpers
################################################################################
sub create_buttons4partitions {
- my ($kind, $totalsectors, @parts) = @_;
+ my ($kind, $totalsectors, @all_parts) = @_;
- $width = max($width, 0.9 * second($w->{window}->window->get_size)) if $w->{window}->window;
+ if ($w->{window}->get_window) {
+ my $windowwidth = $w->{window}->get_allocated_width;
+ $windowwidth = $::real_windowwidth if $windowwidth <= 1;
+ $width = $windowwidth - first(get_action_box_size()) - 25;
+ }
+
+ my @parts = grep { $_->{size} > MB(2) || !isEmpty($_) } @all_parts;
my $ratio = $totalsectors ? ($width - @parts * $minwidth) / $totalsectors : 1;
- while (1) {
+ my $i = 1;
+ while ($i < 30) {
+ $i++;
my $totalwidth = sum(map { $_->{size} * $ratio + $minwidth } @parts);
$totalwidth <= $width and last;
$ratio /= $totalwidth / $width * 1.1;
}
+ my $current_button;
+ my $set_current_button = sub {
+ my ($w) = @_;
+ $current_button->set_active(0) if $current_button;
+ ($current_button = $w)->set_active(1);
+ };
+
foreach my $entry (@parts) {
- my $w = new Gtk::Button($entry->{mntpoint} || '') or die '';
- $w->signal_connect(focus_in_event => sub { current_entry_changed($kind, $entry) });
- $w->signal_connect(button_press_event => sub { current_entry_changed($kind, $entry) });
+ if (isRawLUKS($entry) && $entry->{dm_active}) {
+ my $p = find { $entry->{dm_name} eq $_->{dmcrypt_name} } @{$all_hds->{dmcrypts}};
+ $entry = $p if $p;
+ }
+ my $info = $entry->{mntpoint} || $entry->{device_LABEL} || '';
+ $info .= "\n" . ($entry->{size} ? formatXiB($entry->{size}, 512) : N("Unknown")) if $info;
+ my $w = ($info ? Gtk3::ToggleButton->new_with_label($info) : Gtk3::ToggleButton->new) or internal_error('new_with_label');
+ $info and $w->get_child->set_ellipsize('end');
+ $w->set_tooltip_text($info);
+ $w->signal_connect(clicked => sub {
+ $current_button != $w or return;
+ current_entry_changed($kind, $entry);
+ $set_current_button->($w);
+ });
$w->signal_connect(key_press_event => sub {
- my ($w, $e) = @_;
- $e->{state} & 4 or return;
- my $c = chr $e->{keyval};
+ my (undef, $event) = @_;
+ member('control-mask', @{$event->state}) && $w == $current_button or return;
+ my $c = chr $event->keyval;
foreach my $s (diskdrake::interactive::part_possible_actions($in, kind2hd($kind), $entry, $all_hds)) {
${{
@@ -289,10 +389,19 @@ sub create_buttons4partitions {
last;
}
});
- $w->set_name("PART_" . type2name($entry->{type}));
- $w->set_usize($entry->{size} * $ratio + $minwidth, 0);
- gtkpack__($kind->{display_box}, $w);
- $w->grab_focus if $current_entry && fsedit::is_same_part($current_entry, $entry);
+ if (isLUKS($entry) || isRawLUKS($entry)) {
+ $w->set_image(gtknew("Image", file => "security-strong"));
+ }
+ my @colorized_fs_types = qw(ext3 ext4 xfs swap vfat ntfs ntfs-3g exfat);
+ $w->set_name("PART_" . (isEmpty($entry) ? 'empty' :
+ $entry->{fs_type} && member($entry->{fs_type}, @colorized_fs_types) ? $entry->{fs_type} :
+ 'other'));
+ $w->set_size_request($entry->{size} * $ratio + $minwidth, 0);
+ gtkpack($kind->{display_box}, $w);
+ if ($current_entry && fsedit::are_same_partitions($current_entry, $entry)) {
+ $set_current_button->($w);
+ $w->grab_focus;
+ }
}
}
@@ -300,18 +409,18 @@ sub create_buttons4partitions {
################################################################################
# disks: helpers
################################################################################
-sub current_hd {
- $current_kind->{type} eq 'hd' or die 'current_hd called but $current_kind is not an hd';
+sub current_hd() {
+ $current_kind->{type} =~ /hd|lvm/ or die 'current_hd called but $current_kind is not an hd (' . $current_kind->{type} . ')';
$current_kind->{val};
}
-sub current_part {
+sub current_part() {
current_hd();
$current_entry;
}
sub kind2hd {
my ($kind) = @_;
- $kind->{type} =~ /hd|lvm/ ? $kind->{val} : {}
+ $kind->{type} =~ /hd|lvm/ ? $kind->{val} : bless({}, 'partition_table::raw');
}
sub hd2kind {
@@ -320,43 +429,63 @@ sub hd2kind {
}
sub filesystems_button_box() {
- my @types = (__("Ext2"), __("Journalised FS"), __("Swap"), arch() =~ /sparc/ ? __("SunOS") : arch() eq "ppc" ? __("HFS") : __("FAT"),
- __("Other"), __("Empty"));
- my %name2type = (Ext2 => 0x83, 'Journalised FS' => 0x483, Swap => 0x82, Other => 1, FAT => 0xb, HFS => 0x402);
-
- gtkpack(new Gtk::HBox(0,0),
- _("Filesystem types:"),
- map { my $w = new Gtk::Button(translate($_));
- my $t = $name2type{$_};
- $w->signal_connect(clicked => sub { try_('', \&createOrChangeType, $t, current_hd(), current_part()) });
- $w->can_focus(0);
- $w->set_name($_);
+ my @types = (N_("Ext4"), N_("XFS"), N_("Swap"), N_("Windows"),
+ N_("Other"), N_("Empty"));
+ my %name2fs_type = (Ext3 => 'ext3', Ext4 => 'ext4', 'XFS' => 'xfs', Swap => 'swap', Other => 'other', "Windows" => 'vfat', HFS => 'hfs');
+
+ gtkpack(Gtk3::HBox->new,
+ map {
+ my $t = $name2fs_type{$_};
+ my $w = gtknew('Button', text => translate($_), widget_name => 'PART_' . ($t || 'empty'),
+ tip => N("Filesystem types:"),
+ clicked => sub { try_('', \&createOrChangeType, $t, current_hd(), current_part()) });
+ $w->set_can_focus(0);
$w;
} @types);
}
sub createOrChangeType {
- my ($in, $type, $hd, $part, $all_hds) = @_;
+ my ($in, $fs_type, $hd, $part, $all_hds) = @_;
- $part ||= !fsedit::get_fstab($hd) &&
- { type => 0, start => 1, size => $hd->{totalsectors} - 1 };
+ $part ||= !fs::get::hds_fstab($hd) &&
+ { pt_type => 0, start => 1, size => $hd->{totalsectors} - 1 };
$part or return;
- if ($type == 1) {
- $in->ask_warn('', _("Use ``%s'' instead", $part->{type} ? _("Type") : _("Create")));
- } elsif (!$type) {
- $in->ask_warn('', _("Use ``%s'' instead", _("Delete"))) if $part->{type};
- } elsif ($part->{type}) {
- return unless $::expert;
- return if $type == $part->{type};
- isBusy($part) and $in->ask_warn('', _("Use ``Unmount'' first")), return;
- diskdrake::interactive::ask_alldatawillbelost($in, $part, __("After changing type of partition %s, all data on this partition will be lost")) or return;
- diskdrake::interactive::check_type($in, $type, $hd, $part) and fsedit::change_type($type, $hd, $part);
- } else {
- $part->{type} = $type;
+ if ($fs_type eq 'other') {
+ if (isEmpty($part)) {
+ try('Create', $hd, $part);
+ } else {
+ try('Type', $hd, $part);
+ }
+ } elsif (!$fs_type) {
+ if (isEmpty($part)) {
+ $in->ask_warn(N("Warning"), N("This partition is already empty"));
+ } else {
+ try('Delete', $hd, $part);
+ }
+ } elsif (isEmpty($part)) {
+ fs::type::set_fs_type($part, $fs_type);
diskdrake::interactive::Create($in, $hd, $part, $all_hds);
+ } else {
+ return if $fs_type eq $part->{fs_type};
+ $in->ask_warn('', isBusy($part) ? N("Use ``Unmount'' first") : N("Use ``%s'' instead (in expert mode)", N("Type")));
}
}
+sub kind2parts {
+ my ($kind) = @_;
+ my $v = $kind->{val};
+ my @parts =
+ $kind->{type} eq 'raid' ? grep { $_ } @$v :
+ $kind->{type} eq 'loopback' ? @$v : fs::get::hds_fstab_and_holes($v);
+ @parts;
+}
+
+sub kind2sectors {
+ my ($kind, @parts) = @_;
+ my $v = $kind->{val};
+ $kind->{type} =~ /raid|loopback/ ? sum(map { $_->{size} } @parts) : $v->{totalsectors};
+}
+
################################################################################
# lvms: helpers
################################################################################
@@ -368,14 +497,19 @@ sub lvm2kind {
################################################################################
# raids: helpers
################################################################################
-sub raid2kind {
+sub raid2kind() {
{ type => 'raid', name => 'raid', val => $all_hds->{raids} };
}
+sub raid2real_kind {
+ my ($raid) = @_;
+ { type => 'raid', name => 'raid', val => $raid };
+}
+
################################################################################
# loopbacks: helpers
################################################################################
-sub loopback2kind {
+sub loopback2kind() {
{ type => 'loopback', name => 'loopback', val => $all_hds->{loopbacks} };
}