Refactor activate_mount_partition() and toggle_busy_state() (#775932)

These two methods had a lot of repeated and common code.  Both determine
if the partition has any pending operations, notify the user that
changing the busy status can not be performed, and report any errors
when changing the status.

Extract the common code into sub-functions check_toggle_busy_allowed()
and show_toggle_failure_dialog() to handle showing the message dialogs.
Also refactor toggle_busy_state() to make it clear that it handles 5
cases of swapon, swapoff, activate VG, deactivate VG and unmount file
system.

Also remove out of date comment near the top of toggle_busy_state()
stating there can only be pending operations for inactive partitions is
out of date.  Some file systems can be resized while online and
partition naming is allowed whatever the busy status of the file system.

Bug 775932 - Refactor mostly applying of operations
This commit is contained in:
Mike Fleetwood 2016-09-11 14:52:47 +01:00 committed by Curtis Gedak
parent bfc16bd4a6
commit a5f2c9937b
2 changed files with 153 additions and 160 deletions

View File

@ -177,6 +177,9 @@ private:
void activate_delete(); void activate_delete();
void activate_info(); void activate_info();
void activate_format( GParted::FILESYSTEM new_fs ); void activate_format( GParted::FILESYSTEM new_fs );
bool check_toggle_busy_allowed( const Glib::ustring & disallowed_msg );
void show_toggle_failure_dialog( const Glib::ustring & failure_summary,
const Glib::ustring & marked_up_error );
void toggle_busy_state() ; void toggle_busy_state() ;
void activate_mount_partition( unsigned int index ) ; void activate_mount_partition( unsigned int index ) ;
void activate_disklabel() ; void activate_disklabel() ;

View File

@ -2265,138 +2265,157 @@ bool Win_GParted::unmount_partition( const Partition & partition, Glib::ustring
return true; return true;
} }
bool Win_GParted::check_toggle_busy_allowed( const Glib::ustring & disallowed_msg )
{
int operation_count = partition_in_operation_queue_count( *selected_partition_ptr );
if ( operation_count > 0 )
{
Glib::ustring primary_msg = String::ucompose(
/* TO TRANSLATORS: Singular case looks like 1 operation is currently pending for partition /dev/sdb1 */
ngettext( "%1 operation is currently pending for partition %2",
/* TO TRANSLATORS: Plural case looks like 3 operations are currently pending for partition /dev/sdb1 */
"%1 operations are currently pending for partition %2",
operation_count ),
operation_count,
selected_partition_ptr->get_path() );
Gtk::MessageDialog dialog( *this,
primary_msg,
false,
Gtk::MESSAGE_INFO,
Gtk::BUTTONS_OK,
true );
Glib::ustring secondary_msg = disallowed_msg + "\n" +
_("Use the Edit menu to undo, clear or apply pending operations.");
dialog.set_secondary_text( secondary_msg );
dialog.run();
return false;
}
return true;
}
void Win_GParted::show_toggle_failure_dialog( const Glib::ustring & failure_summary,
const Glib::ustring & marked_up_error )
{
Gtk::MessageDialog dialog( *this,
failure_summary,
false,
Gtk::MESSAGE_ERROR,
Gtk::BUTTONS_OK,
true );
dialog.set_secondary_text( marked_up_error, true );
dialog.run();
}
void Win_GParted::toggle_busy_state() void Win_GParted::toggle_busy_state()
{ {
g_assert( selected_partition_ptr != NULL ); // Bug: Partition callback without a selected partition g_assert( selected_partition_ptr != NULL ); // Bug: Partition callback without a selected partition
g_assert( valid_display_partition_ptr( selected_partition_ptr ) ); // Bug: Not pointing at a valid display partition object g_assert( valid_display_partition_ptr( selected_partition_ptr ) ); // Bug: Not pointing at a valid display partition object
int operation_count = partition_in_operation_queue_count( *selected_partition_ptr ); enum Action
bool success = false ;
Glib::ustring cmd;
Glib::ustring output;
Glib::ustring error;
if ( operation_count > 0 )
{ {
//Note that this situation will only occur when trying to swapon a partition NONE = 0,
// or activate the Volume Group of a Physical Volume. This is because SWAPOFF = 1,
// GParted does not permit queueing operations on partitions that are SWAPON = 2,
// currently active (i.e., swap enabled, mounted or active VG). Hence DEACTIVATE_VG = 3,
// this situation will not occur for the swapoff, unmount or deactivate VG ACTIVATE_VG = 4,
// actions that this method handles. UNMOUNT = 5
};
/*TO TRANSLATORS: Singular case looks like 1 operation is currently pending for partition /dev/sdd8. */ Action action = NONE;
Glib::ustring tmp_msg = Glib::ustring disallowed_msg;
String::ucompose( ngettext( "%1 operation is currently pending for partition %2" Glib::ustring pulse_msg;
, "%1 operations are currently pending for partition %2" Glib::ustring failure_msg;
, operation_count if ( selected_partition_ptr->filesystem == FS_LINUX_SWAP && selected_partition_ptr->busy )
) {
, operation_count action = SWAPOFF;
, selected_partition_ptr->get_path() disallowed_msg = _("The swapoff action cannot be performed when there are operations pending for the partition.");
) ; pulse_msg = String::ucompose( _("Deactivating swap on %1"), selected_partition_ptr->get_path() );
Gtk::MessageDialog dialog( *this failure_msg = _("Could not deactivate swap");
, tmp_msg
, false
, Gtk::MESSAGE_INFO
, Gtk::BUTTONS_OK
, true
) ;
if ( selected_partition_ptr->filesystem == FS_LINUX_SWAP )
{
tmp_msg = _( "The swapon action cannot be performed if an operation is pending for the partition." ) ;
tmp_msg += "\n" ;
tmp_msg += _( "Use the Edit menu to undo, clear, or apply operations before using swapon with this partition." ) ;
}
else if ( selected_partition_ptr->filesystem == FS_LVM2_PV )
{
tmp_msg = _( "The activate Volume Group action cannot be performed if an operation is pending for the partition." ) ;
tmp_msg += "\n" ;
tmp_msg += _( "Use the Edit menu to undo, clear, or apply operations before using activate Volume Group with this partition." ) ;
}
dialog .set_secondary_text( tmp_msg ) ;
dialog .run() ;
return ;
} }
else if ( selected_partition_ptr->filesystem == FS_LINUX_SWAP && ! selected_partition_ptr->busy )
if ( selected_partition_ptr->filesystem == FS_LINUX_SWAP )
{ {
show_pulsebar( action = SWAPON;
String::ucompose( disallowed_msg = _("The swapon action cannot be performed when there are operations pending for the partition.");
selected_partition_ptr->busy ? _("Deactivating swap on %1") : _("Activating swap on %1"), pulse_msg = String::ucompose( _("Activating swap on %1"), selected_partition_ptr->get_path() );
selected_partition_ptr->get_path() ) ); failure_msg = _("Could not activate swap");
if ( selected_partition_ptr->busy )
cmd = "swapoff -v " + selected_partition_ptr->get_path();
else
cmd = "swapon -v " + selected_partition_ptr->get_path();
success = ! Utils::execute_command( cmd, output, error );
hide_pulsebar();
if ( ! success )
{
Gtk::MessageDialog dialog(
*this,
selected_partition_ptr->busy ? _("Could not deactivate swap") : _("Could not activate swap"),
false,
Gtk::MESSAGE_ERROR,
Gtk::BUTTONS_OK,
true ) ;
dialog.set_secondary_text( "# " + cmd + "\n" + error );
dialog.run() ;
}
} }
else if ( selected_partition_ptr->filesystem == FS_LVM2_PV ) else if ( selected_partition_ptr->filesystem == FS_LVM2_PV && selected_partition_ptr->busy )
{ {
show_pulsebar( action = DEACTIVATE_VG;
String::ucompose( disallowed_msg = _("The deactivate Volume Group action cannot be performed when there are operations pending for the partition.");
selected_partition_ptr->busy ? _("Deactivating Volume Group %1") pulse_msg = String::ucompose( _("Deactivating Volume Group %1"),
: _("Activating Volume Group %1"), selected_partition_ptr->get_mountpoint() ); // VGNAME from point point
// VGNAME from mount point failure_msg = _("Could not deactivate Volume Group");
selected_partition_ptr->get_mountpoint() ) ); }
if ( selected_partition_ptr->busy ) else if ( selected_partition_ptr->filesystem == FS_LVM2_PV && ! selected_partition_ptr->busy )
// VGNAME from mount point {
cmd = "lvm vgchange -a n " + selected_partition_ptr->get_mountpoint(); action = ACTIVATE_VG;
else disallowed_msg = _("The activate Volume Group action cannot be performed when there are operations pending for the partition.");
cmd = "lvm vgchange -a y " + selected_partition_ptr->get_mountpoint(); pulse_msg = String::ucompose( _("Activating Volume Group %1"),
success = ! Utils::execute_command( cmd, output, error ); selected_partition_ptr->get_mountpoint() ); // VGNAME from point point
hide_pulsebar(); failure_msg = _("Could not activate Volume Group");
if ( ! success )
{
Gtk::MessageDialog dialog(
*this,
selected_partition_ptr->busy ? _("Could not deactivate Volume Group")
: _("Could not activate Volume Group"),
false,
Gtk::MESSAGE_ERROR,
Gtk::BUTTONS_OK,
true ) ;
dialog.set_secondary_text( "# " + cmd + "\n" + error );
dialog.run() ;
}
} }
else if ( selected_partition_ptr->busy ) else if ( selected_partition_ptr->busy )
{ {
show_pulsebar( String::ucompose( _("Unmounting %1"), selected_partition_ptr->get_path() ) ); action = UNMOUNT;
success = unmount_partition( *selected_partition_ptr, error ); disallowed_msg = _("The unmount action cannot be performed when there are operations pending for the partition.");
hide_pulsebar(); pulse_msg = String::ucompose( _("Unmounting %1"), selected_partition_ptr->get_path() );
if ( ! success ) failure_msg = String::ucompose( _("Could not unmount %1"), selected_partition_ptr->get_path() );
{
Gtk::MessageDialog dialog( *this,
String::ucompose( _("Could not unmount %1"),
selected_partition_ptr->get_path() ),
false,
Gtk::MESSAGE_ERROR,
Gtk::BUTTONS_OK,
true );
dialog .set_secondary_text( error, true ) ;
dialog.run() ;
}
} }
else
// Impossible. Mounting a file system calls activate_mount_partition().
return;
if ( ! check_toggle_busy_allowed( disallowed_msg ) )
// One or more operations are pending for this partition so changing the
// busy state is not allowed.
//
// After set_valid_operations() has allowed the operations to be queued
// the rest of the code assumes the busy state of the partition won't
// change. Therefore pending operations must prevent changing the busy
// state of the partition.
return;
show_pulsebar( pulse_msg );
bool success = false;
Glib::ustring cmd;
Glib::ustring output;
Glib::ustring error;
Glib::ustring error_msg;
switch ( action )
{
case SWAPOFF:
cmd = "swapoff -v " + selected_partition_ptr->get_path();
success = ! Utils::execute_command( cmd, output, error );
error_msg = "<i># " + cmd + "\n" + error + "</i>";
break;
case SWAPON:
cmd = "swapon -v " + selected_partition_ptr->get_path();
success = ! Utils::execute_command( cmd, output, error );
error_msg = "<i># " + cmd + "\n" + error + "</i>";
break;
case DEACTIVATE_VG:
cmd = "lvm vgchange -a n " + selected_partition_ptr->get_mountpoint();
success = ! Utils::execute_command( cmd, output, error );
error_msg = "<i># " + cmd + "\n" + error + "</i>";
break;
case ACTIVATE_VG:
cmd = "lvm vgchange -a y " + selected_partition_ptr->get_mountpoint();
success = ! Utils::execute_command( cmd, output, error );
error_msg = "<i># " + cmd + "\n" + error + "</i>";
break;
case UNMOUNT:
success = unmount_partition( *selected_partition_ptr, error_msg );
break;
default:
// Impossible
break;
}
hide_pulsebar();
if ( ! success )
show_toggle_failure_dialog( failure_msg, error_msg );
menu_gparted_refresh_devices() ; menu_gparted_refresh_devices() ;
} }
@ -2406,38 +2425,17 @@ void Win_GParted::activate_mount_partition( unsigned int index )
g_assert( selected_partition_ptr != NULL ); // Bug: Partition callback without a selected partition g_assert( selected_partition_ptr != NULL ); // Bug: Partition callback without a selected partition
g_assert( valid_display_partition_ptr( selected_partition_ptr ) ); // Bug: Not pointing at a valid display partition object g_assert( valid_display_partition_ptr( selected_partition_ptr ) ); // Bug: Not pointing at a valid display partition object
int operation_count = partition_in_operation_queue_count( *selected_partition_ptr ); Glib::ustring disallowed_msg = _("The mount action cannot be performed when an operation is pending for the partition.");
if ( operation_count > 0 ) if ( ! check_toggle_busy_allowed( disallowed_msg ) )
{ // One or more operations are pending for this partition so changing the
/*TO TRANSLATORS: Plural case looks like 4 operations are currently pending for partition /dev/sdd8. */ // busy state by mounting the file system is not allowed.
Glib::ustring tmp_msg = return;
String::ucompose( ngettext( "%1 operation is currently pending for partition %2"
, "%1 operations are currently pending for partition %2"
, operation_count
)
, operation_count
, selected_partition_ptr->get_path()
) ;
Gtk::MessageDialog dialog( *this
, tmp_msg
, false
, Gtk::MESSAGE_INFO
, Gtk::BUTTONS_OK
, true
) ;
tmp_msg = _( "The mount action cannot be performed if an operation is pending for the partition." ) ;
tmp_msg += "\n" ;
tmp_msg += _( "Use the Edit menu to undo, clear, or apply operations before using mount with this partition." ) ;
dialog .set_secondary_text( tmp_msg ) ;
dialog .run() ;
return ;
}
bool success = false ; bool success;
Glib::ustring cmd; Glib::ustring cmd;
Glib::ustring output; Glib::ustring output;
Glib::ustring error; Glib::ustring error;
Glib::ustring message; Glib::ustring error_msg;
show_pulsebar( String::ucompose( _("mounting %1 on %2"), show_pulsebar( String::ucompose( _("mounting %1 on %2"),
selected_partition_ptr->get_path(), selected_partition_ptr->get_path(),
@ -2449,7 +2447,7 @@ void Win_GParted::activate_mount_partition( unsigned int index )
success = ! Utils::execute_command( cmd, output, error ); success = ! Utils::execute_command( cmd, output, error );
if ( ! success ) if ( ! success )
{ {
message = "# " + cmd + "\n" + error; error_msg = "<i># " + cmd + "\n" + error + "</i>";
Glib::ustring type = Utils::get_filesystem_kernel_name( selected_partition_ptr->filesystem ); Glib::ustring type = Utils::get_filesystem_kernel_name( selected_partition_ptr->filesystem );
if ( ! type.empty() ) if ( ! type.empty() )
@ -2460,24 +2458,16 @@ void Win_GParted::activate_mount_partition( unsigned int index )
" \"" + selected_partition_ptr->get_mountpoints()[index] + "\""; " \"" + selected_partition_ptr->get_mountpoints()[index] + "\"";
success = ! Utils::execute_command( cmd, output, error ); success = ! Utils::execute_command( cmd, output, error );
if ( ! success ) if ( ! success )
message += "\n# " + cmd + "\n" + error; error_msg += "\n<i># " + cmd + "\n" + error + "</i>";
} }
} }
hide_pulsebar(); hide_pulsebar();
if ( ! success ) if ( ! success )
{ {
Gtk::MessageDialog dialog( *this, Glib::ustring failure_msg = String::ucompose( _("Could not mount %1 on %2"),
String::ucompose( _("Could not mount %1 on %2"), selected_partition_ptr->get_path(),
selected_partition_ptr->get_path(), selected_partition_ptr->get_mountpoints()[index] );
selected_partition_ptr->get_mountpoints()[index] ), show_toggle_failure_dialog( failure_msg, error_msg );
false,
Gtk::MESSAGE_ERROR,
Gtk::BUTTONS_OK,
true );
dialog.set_secondary_text( message );
dialog.run() ;
} }
menu_gparted_refresh_devices() ; menu_gparted_refresh_devices() ;