Merge overlapping operations (#438573)

When a new operation is added to operations list, check if a merge
is possible depending on the operation type:

    OPERATION_RESIZE_MOVE:  2 consecutive "resize" operations on the
                            same  partition
OPERATION_LABEL_PARTITION:  2 "label change" operations (need not be
                            consecutive) on the same partition
          OPERATION_CHECK:  2 "check" operations (need not be
                            consecutive) on the same partition
         OPERATION_FORMAT:  2 consecutive "format" operations on the
                            same partition

Closes Bug #438573 - Cancel out overlapping actions

Also fix a bug when copying partition using the Partition::Set(...)
method.  This method did not initialize "sectors_used" and
"sectors_unused" members.
This commit is contained in:
Jérôme Dumesnil 2011-10-05 12:15:16 -06:00 committed by Curtis Gedak
parent f41d5c07a0
commit b10349ae37
3 changed files with 105 additions and 0 deletions

View File

@ -60,6 +60,7 @@ private:
void Fill_Label_Device_Info( bool clear = false );
void Add_Operation( Operation * operation, int index = -1 ) ;
bool Merge_Operations( int first, int second );
void Refresh_Visual();
bool Quit_Check_Operations();
void set_valid_operations() ;

View File

@ -387,6 +387,7 @@ void DrawingAreaVisualDisk::on_size_allocate( Gtk::Allocation & allocation )
calc_position_and_height( visual_partitions, MAIN_BORDER, MAIN_BORDER ) ;//0, 0 ) ;
calc_used_unused( visual_partitions ) ;
calc_text( visual_partitions ) ;
queue_draw();
}
int DrawingAreaVisualDisk::spreadout_leftover_px( std::vector<visual_partition> & visual_partitions, int pixels )

View File

@ -720,6 +720,66 @@ void Win_GParted::Add_Operation( Operation * operation, int index )
}
}
bool Win_GParted::Merge_Operations( int first, int second )
{
// Two resize operations of the same partition
if ( operations[ first ]->type == OPERATION_RESIZE_MOVE &&
operations[ second ]->type == OPERATION_RESIZE_MOVE &&
operations[ first ]->partition_new == operations[ second ]->partition_original
)
{
operations[ first ]->partition_new = operations[ second ]->partition_new;
operations[ first ]->create_description() ;
remove_operation( second );
Refresh_Visual();
return true;
}
// Two label change operations on the same partition
else if ( operations[ first ]->type == OPERATION_LABEL_PARTITION &&
operations[ second ]->type == OPERATION_LABEL_PARTITION &&
operations[ first ]->partition_new == operations[ second ]->partition_original
)
{
operations[ first ]->partition_new.label = operations[ second ]->partition_new.label;
operations[ first ]->create_description() ;
remove_operation( second );
Refresh_Visual();
return true;
}
// Two check operations of the same partition
else if ( operations[ first ]->type == OPERATION_CHECK &&
operations[ second ]->type == OPERATION_CHECK &&
operations[ first ]->partition_original == operations[ second ]->partition_original
)
{
remove_operation( second );
Refresh_Visual();
return true;
}
// Two format operations of the same partition
else if ( operations[ first ]->type == OPERATION_FORMAT &&
operations[ second ]->type == OPERATION_FORMAT &&
operations[ first ]->partition_new == operations[ second ]->partition_original
)
{
operations[ first ]->partition_new = operations[ second ]->partition_new;
operations[ first ]->create_description() ;
remove_operation( second );
Refresh_Visual();
return true;
}
return false;
}
void Win_GParted::Refresh_Visual()
{
std::vector<Partition> partitions = devices[ current_device ] .partitions ;
@ -1478,6 +1538,12 @@ void Win_GParted::activate_resize()
dialog .set_secondary_text( tmp_msg ) ;
dialog .run() ;
}
// Try to merge with previous operation
if ( operations .size() >= 2 )
{
Merge_Operations(operations .size() - 2, operations .size() - 1);
}
}
}
}
@ -1666,6 +1732,12 @@ void Win_GParted::activate_delete()
new_count += 1 ;
// Verify if the two operations can be merged
for ( int t = 0 ; t < static_cast<int>( operations .size() - 1 ) ; t++ )
{
Merge_Operations( t, t+1 );
}
Refresh_Visual();
if ( ! operations .size() )
@ -1740,6 +1812,8 @@ void Win_GParted::activate_format( GParted::FILESYSTEM new_fs )
devices[ current_device ] .sector_size,
selected_partition .inside_extended,
false ) ;
part_temp .Set_Unused( selected_partition .sectors_unused );
part_temp .set_used( 0 );
part_temp .status = GParted::STAT_FORMATTED ;
@ -1777,6 +1851,12 @@ void Win_GParted::activate_format( GParted::FILESYSTEM new_fs )
operation ->icon = render_icon( Gtk::Stock::CONVERT, Gtk::ICON_SIZE_MENU );
Add_Operation( operation ) ;
// Try to merge with previous operation
if ( operations .size() >= 2 )
{
Merge_Operations( operations .size() - 2, operations .size() - 1 );
}
}
}
@ -2190,6 +2270,16 @@ void Win_GParted::activate_check()
operation ->icon = render_icon( Gtk::Stock::EXECUTE, Gtk::ICON_SIZE_MENU );
Add_Operation( operation ) ;
// Verify if the two operations can be merged
for ( unsigned int t = 0 ; t < operations .size() - 1 ; t++ )
{
if ( operations[ t ] ->type == OPERATION_CHECK )
{
if( Merge_Operations( t, operations .size() -1 ) )
break;
}
}
}
void Win_GParted::activate_label_partition()
@ -2213,13 +2303,26 @@ void Win_GParted::activate_label_partition()
devices[ current_device ] .sector_size,
selected_partition .inside_extended,
false ) ;
part_temp .Set_Unused( selected_partition.sectors_unused );
part_temp .set_used( selected_partition.sectors_used );
part_temp .label = dialog .get_new_label();
Operation * operation = new OperationLabelPartition( devices[ current_device ],
selected_partition, part_temp ) ;
operation ->icon = render_icon( Gtk::Stock::EXECUTE, Gtk::ICON_SIZE_MENU );
Add_Operation( operation ) ;
// Verify if the two operations can be merged
for ( unsigned int t = 0 ; t < operations .size() - 1 ; t++ )
{
if ( operations[ t ] ->type == OPERATION_LABEL_PARTITION )
{
if( Merge_Operations( t, operations .size() -1 ) )
break;
}
}
}
}