[gparted] Merge overlapping operations (#438573)



commit b10349ae37df06b7bf7de91ea93a3913535ade3a
Author: JÃrÃme Dumesnil <jerome dumesnil gmail com>
Date:   Wed Oct 5 12:15:16 2011 -0600

    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.

 include/Win_GParted.h        |    1 +
 src/DrawingAreaVisualDisk.cc |    1 +
 src/Win_GParted.cc           |  103 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 105 insertions(+), 0 deletions(-)
---
diff --git a/include/Win_GParted.h b/include/Win_GParted.h
index 0235de7..9326c51 100644
--- a/include/Win_GParted.h
+++ b/include/Win_GParted.h
@@ -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() ;
diff --git a/src/DrawingAreaVisualDisk.cc b/src/DrawingAreaVisualDisk.cc
index 1ef54e6..5f3c2a6 100644
--- a/src/DrawingAreaVisualDisk.cc
+++ b/src/DrawingAreaVisualDisk.cc
@@ -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 ) 
diff --git a/src/Win_GParted.cc b/src/Win_GParted.cc
index 4f29ada..4ad1243 100644
--- a/src/Win_GParted.cc
+++ b/src/Win_GParted.cc
@@ -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;
+			}
+		}
 	}
 }
 	



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]