From fd8c131b2659261843ea286f08882427cd942488 Mon Sep 17 00:00:00 2001
From: Chantara Tith <tith.chantara@gmail.com>
Date: Fri, 18 Mar 2016 17:09:50 +0700
Subject: [PATCH] implement free-space partition replace install

---
 src/modules/partition/core/PartUtils.cpp |  3 --
 src/modules/partition/gui/ChoicePage.cpp | 59 +++++++++++++++++-------
 2 files changed, 43 insertions(+), 19 deletions(-)

diff --git a/src/modules/partition/core/PartUtils.cpp b/src/modules/partition/core/PartUtils.cpp
index 32872e048c..9f7bc30e77 100644
--- a/src/modules/partition/core/PartUtils.cpp
+++ b/src/modules/partition/core/PartUtils.cpp
@@ -37,9 +37,6 @@ namespace PartUtils
 bool
 canBeReplaced( Partition* candidate )
 {
-    if ( KPMHelpers::isPartitionFreeSpace( candidate ) )
-        return false;
-
     bool ok = false;
     double requiredStorageGB = Calamares::JobQueue::instance()
                                     ->globalStorage()
diff --git a/src/modules/partition/gui/ChoicePage.cpp b/src/modules/partition/gui/ChoicePage.cpp
index 38e5ba77f7..51c55e39c0 100644
--- a/src/modules/partition/gui/ChoicePage.cpp
+++ b/src/modules/partition/gui/ChoicePage.cpp
@@ -579,22 +579,49 @@ ChoicePage::doReplaceSelectedPartition( const QModelIndex& current,
             m_core->revertDevice( selectedDevice() );
         }
 
-        // TODO: get the selected partition in the immutable model with PartitionPtrRole,
-        //       check KPMHelpers::isPartitionFreeSpace, if true then don't replace but
-        //       just m_core->createPartition for the same first/last sector as the
-        //       free space "partition" in the immutable model.
-        //       Also set parent correctly (see PartitionActions::doReplacePartition)
-        //       as well as mount point and format.
-
-        // We can't use the PartitionPtrRole because we need to make changes to the
-        // main DeviceModel, not the immutable copy.
-        QString partPath = current.data( PartitionModel::PartitionPathRole ).toString();
-        Partition* partition = KPMHelpers::findPartitionByPath( { selectedDevice() },
-                                                                partPath );
-        if ( partition )
-            PartitionActions::doReplacePartition( m_core,
-                                                  selectedDevice(),
-                                                  partition );
+        // if the partition is unallocated(free space), we don't replace it but create new one 
+        // with the same first and last sector
+        Partition* selectedPartition = (Partition *)( current.data( PartitionModel::PartitionPtrRole ).value< void* >() );
+        if ( KPMHelpers::isPartitionFreeSpace( selectedPartition ) )
+        {
+            PartitionRole newRoles = PartitionRole( PartitionRole::Primary );
+            PartitionNode* newParent = selectedDevice()->partitionTable();
+
+            if ( selectedPartition->parent() )
+            {
+                Partition* parent = dynamic_cast< Partition* >( selectedPartition->parent() );
+                if ( parent && parent->roles().has( PartitionRole::Extended ) )
+                {
+                    newRoles = PartitionRole( PartitionRole::Logical );
+                    newParent = KPMHelpers::findPartitionByPath( { selectedDevice() }, parent->partitionPath() );
+                }
+            }
+
+            Partition* newPartition = KPMHelpers::createNewPartition(
+                    newParent,
+                    *selectedDevice(),
+                    newRoles,
+                    FileSystem::Ext4,
+                    selectedPartition->firstSector(),
+                    selectedPartition->lastSector() );
+
+            PartitionInfo::setMountPoint( newPartition, "/" );
+            PartitionInfo::setFormat( newPartition, true );
+
+            m_core->createPartition( selectedDevice(), newPartition);
+        }
+        else
+        {
+            // We can't use the PartitionPtrRole because we need to make changes to the
+            // main DeviceModel, not the immutable copy.
+            QString partPath = current.data( PartitionModel::PartitionPathRole ).toString();
+            selectedPartition = KPMHelpers::findPartitionByPath( { selectedDevice() },
+                                                                    partPath );
+            if ( selectedPartition )
+                PartitionActions::doReplacePartition( m_core,
+                                                      selectedDevice(),
+                                                      selectedPartition );
+        }
     } ),
     [=]
     {
-- 
GitLab