[gparted] Replace open coded merge of resize/move into create operation (#755214)



commit 5793c5ac03bea5b4818309e5755803b00feeb016
Author: Mike Fleetwood <mike fleetwood googlemail com>
Date:   Wed Sep 16 22:23:12 2015 +0100

    Replace open coded merge of resize/move into create operation (#755214)
    
    For the case of resizing/moving a new, not yet created partition,
    activate_resize() open coded the merge operation.  Again this code has
    existed in GParted since before version 0.0.5 and the current code
    history in Git.
    
    Replace the necessary code so that an explicit merge_operations() call
    is used instead; along with the other case of resizing/moving an
    existing partition.
    
    NOTES:
    
    This commit changes the merge direction.  The old coded merged forward
    by removing the old create operation and adding a new create operation
    with the new size.  This was bad because with multiple pending create
    operations, each merged resize operation reordered those create
    operations.  Then when the operations were applied the partitions were
    created and therefore numbered in a different order to that shown in
    disk graphic.
    
    The new code merges backwards by updating the initial create operation
    with the new size.  This maintains the create operation order so that
    when applied the partitions are numbered in the same order as shown in
    the disk graphic.
    
    Bug 755214 - Refactor operation merging

 src/OperationCreate.cc |   10 ++++
 src/Win_GParted.cc     |  107 ++++++++++++++++++++----------------------------
 2 files changed, 54 insertions(+), 63 deletions(-)
---
diff --git a/src/OperationCreate.cc b/src/OperationCreate.cc
index 39df030..0a36355 100644
--- a/src/OperationCreate.cc
+++ b/src/OperationCreate.cc
@@ -104,6 +104,16 @@ bool OperationCreate::merge_operations( const Operation & candidate )
                create_description();
                return true;
        }
+       else if ( candidate.type                      == OPERATION_RESIZE_MOVE        &&
+                 candidate.partition_original.status == STAT_NEW                     &&
+                 partition_new                       == candidate.partition_original    )
+       {
+               // Merge a resize/move operation on a not yet created partition with the
+               // earlier operation which will create it.
+               partition_new = candidate.partition_new;
+               create_description();
+               return true;
+       }
 
        return false;
 }
diff --git a/src/Win_GParted.cc b/src/Win_GParted.cc
index defb782..5f03c65 100644
--- a/src/Win_GParted.cc
+++ b/src/Win_GParted.cc
@@ -1705,81 +1705,62 @@ void Win_GParted::activate_resize()
        if ( dialog .run() == Gtk::RESPONSE_OK )
        {
                dialog .hide() ;
-               
+
+               Partition part_temp = dialog.Get_New_Partition( devices[current_device].sector_size );
+               // When resizing/moving a partition which already exists on the disk all
+               // possible operations could be pending so only try merging with the
+               // previous operation.
+               MergeType mergetype = MERGE_LAST_WITH_PREV;
+
                // If selected partition is NEW we simply remove the NEW operation from the list and add
                // it again with the new size and position ( unless it's an EXTENDED )
                if ( selected_partition_ptr->status == STAT_NEW && selected_partition_ptr->type != 
TYPE_EXTENDED )
                {
-                       //remove operation which creates this partition
-                       for ( unsigned int t = 0 ; t < operations .size() ; t++ )
-                       {
-                               if ( operations[t]->partition_new == *selected_partition_ptr )
-                               {
-                                       remove_operation( t ) ;
-                                       
-                                       // And add the new partition to the end of the operations list.
-                                       // Create a suitable partition from the selected partition.
-                                       Partition temp_partition = *selected_partition_ptr;
-                                       temp_partition.Set_Unallocated( devices[current_device].get_path(),
-                                                                       selected_partition_ptr->whole_device,
-                                                                       selected_partition_ptr->sector_start,
-                                                                       selected_partition_ptr->sector_end,
-                                                                       devices[current_device].sector_size,
-                                                                       
selected_partition_ptr->inside_extended );
-
-                                       Operation * operation = new OperationCreate( devices[ current_device 
],
-                                                                                    temp_partition,
-                                                                                    
dialog.Get_New_Partition( devices[current_device].sector_size ) );
-                                       operation ->icon = render_icon( Gtk::Stock::NEW, Gtk::ICON_SIZE_MENU 
);
-
-                                       Add_Operation( operation ) ;
-
-                                       break;
-                               }
-                       }
+                       part_temp.status = STAT_NEW;
+                       // On a partition which is pending creation only resize/move and
+                       // format operations are possible.  These operations are always
+                       // mergeable with the pending operation which will create the
+                       // partition.  Hence merge with any earlier operations to achieve
+                       // this.
+                       mergetype = MERGE_LAST_WITH_ANY;
                }
-               else  // Normal move/resize on existing partition
-               {
-                       Operation * operation = new OperationResizeMove( devices[current_device],
-                                                                        *selected_partition_ptr,
-                                                                        dialog.Get_New_Partition( 
devices[current_device].sector_size) );
-                       operation ->icon = render_icon( Gtk::Stock::GOTO_LAST, Gtk::ICON_SIZE_MENU );
 
-                       Add_Operation( operation ) ;
+               Operation * operation = new OperationResizeMove( devices[current_device],
+                                                                *selected_partition_ptr,
+                                                                part_temp );
+               operation->icon = render_icon( Gtk::Stock::GOTO_LAST, Gtk::ICON_SIZE_MENU );
 
-                       //Display notification if move operation has been queued
-                       if (   operation ->partition_original .sector_start != operation ->partition_new 
.sector_start
-                           && operation ->partition_original .type != TYPE_EXTENDED
-                          )
-                       {
-                               //Warn that move operation might break boot process
-                               Gtk::MessageDialog dialog( *this
-                                                        , _( "Moving a partition might cause your operating 
system to fail to boot" )
-                                                        , false
-                                                        , Gtk::MESSAGE_WARNING
-                                                        , Gtk::BUTTONS_OK
-                                                        , true
-                                                        ) ;
-                               Glib::ustring tmp_msg =
+               // Display warning if moving a non-extended partition which already exists
+               // on the disk.
+               if ( operation->partition_original.status       != STAT_NEW                              &&
+                    operation->partition_original.sector_start != operation->partition_new.sector_start &&
+                    operation->partition_original.type         != TYPE_EXTENDED                            )
+               {
+                       // Warn that move operation might break boot process
+                       Gtk::MessageDialog dialog( *this,
+                                                  _("Moving a partition might cause your operating system to 
fail to boot"),
+                                                  false,
+                                                  Gtk::MESSAGE_WARNING,
+                                                  Gtk::BUTTONS_OK,
+                                                  true );
+                       Glib::ustring tmp_msg =
                                        /*TO TRANSLATORS: looks like   You queued an operation to move the 
start sector of partition /dev/sda3. */
                                        String::ucompose( _( "You have queued an operation to move the start 
sector of partition %1." )
                                                        , operation ->partition_original .get_path()
                                                        ) ;
-                               tmp_msg += _( "  Failure to boot is most likely to occur if you move the 
GNU/Linux partition containing /boot, or if you move the Windows system partition C:." ) ;
-                               tmp_msg += "\n" ;
-                               tmp_msg += _( "You can learn how to repair the boot configuration in the 
GParted FAQ." ) ;
-                               tmp_msg += "\n" ;
-                               tmp_msg += "http://gparted.org/faq.php"; ;
-                               tmp_msg += "\n\n" ;
-                               tmp_msg += _( "Moving a partition might take a very long time to apply." ) ;
-                               dialog .set_secondary_text( tmp_msg ) ;
-                               dialog .run() ;
-                       }
-
-                       // Try to merge this resize/move operation with the previous
-                       // operation only.
-                       merge_operations( MERGE_LAST_WITH_PREV );
+                       tmp_msg += _("  Failure to boot is most likely to occur if you move the GNU/Linux 
partition containing /boot, or if you move the Windows system partition C:.");
+                       tmp_msg += "\n";
+                       tmp_msg += _("You can learn how to repair the boot configuration in the GParted 
FAQ.");
+                       tmp_msg += "\n";
+                       tmp_msg += "http://gparted.org/faq.php";;
+                       tmp_msg += "\n\n";
+                       tmp_msg += _("Moving a partition might take a very long time to apply.");
+                       dialog.set_secondary_text( tmp_msg );
+                       dialog.run();
                }
+
+               Add_Operation( operation );
+               merge_operations( mergetype );
        }
 
        show_operationslist() ;


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