OSDN Git Service

Merge branch 'calamares' into issues-1166
[alterlinux/alterlinux-calamares.git] / src / modules / partition / core / PartitionCoreModule.cpp
index d78ef70..b4cd201 100644 (file)
@@ -41,6 +41,7 @@
 #include "partition/PartitionIterator.h"
 #include "partition/PartitionQuery.h"
 #include "utils/Logger.h"
+#include "utils/Traits.h"
 #include "utils/Variant.h"
 
 // KPMcore
@@ -97,6 +98,59 @@ private:
 
 
 //- DeviceInfo ---------------------------------------------
+// Some jobs have an updatePreview some don't
+DECLARE_HAS_METHOD(updatePreview)
+
+template< typename Job >
+void updatePreview( Job* job, const std::true_type& )
+{
+    job->updatePreview();
+}
+
+template< typename Job >
+void updatePreview( Job* job, const std::false_type& )
+{
+}
+
+template< typename Job >
+void updatePreview( Job* job )
+{
+    updatePreview(job, has_updatePreview<Job>{});
+}
+
+/**
+ * Owns the Device, PartitionModel and the jobs
+ */
+struct PartitionCoreModule::DeviceInfo
+{
+    DeviceInfo( Device* );
+    ~DeviceInfo();
+    QScopedPointer< Device > device;
+    QScopedPointer< PartitionModel > partitionModel;
+    const QScopedPointer< Device > immutableDevice;
+
+    // To check if LVM VGs are deactivated
+    bool isAvailable;
+
+    void forgetChanges();
+    bool isDirty() const;
+
+    const Calamares::JobList& jobs() const { return m_jobs; }
+
+    template< typename Job, typename... Args >
+    Calamares::Job* makeJob(Args... a)
+    {
+        auto* job = new Job( device.get(), a... );
+        updatePreview( job );
+        m_jobs << Calamares::job_ptr( job );
+        return job;
+    }
+
+private:
+    Calamares::JobList m_jobs;
+};
+
+
 PartitionCoreModule::DeviceInfo::DeviceInfo( Device* _device )
     : device( _device )
     , partitionModel( new PartitionModel )
@@ -111,7 +165,7 @@ PartitionCoreModule::DeviceInfo::~DeviceInfo() {}
 void
 PartitionCoreModule::DeviceInfo::forgetChanges()
 {
-    jobs.clear();
+    m_jobs.clear();
     for ( auto it = PartitionIterator::begin( device.data() ); it != PartitionIterator::end( device.data() ); ++it )
     {
         PartitionInfo::reset( *it );
@@ -123,16 +177,18 @@ PartitionCoreModule::DeviceInfo::forgetChanges()
 bool
 PartitionCoreModule::DeviceInfo::isDirty() const
 {
-    if ( !jobs.isEmpty() )
+    if ( !m_jobs.isEmpty() )
     {
         return true;
     }
 
     for ( auto it = PartitionIterator::begin( device.data() ); it != PartitionIterator::end( device.data() ); ++it )
+    {
         if ( PartitionInfo::isDirty( *it ) )
         {
             return true;
         }
+    }
 
     return false;
 }
@@ -284,36 +340,30 @@ PartitionCoreModule::immutableDeviceCopy( const Device* device )
 void
 PartitionCoreModule::createPartitionTable( Device* device, PartitionTable::TableType type )
 {
-    DeviceInfo* info = infoForDevice( device );
-    if ( info )
+    auto* deviceInfo = infoForDevice( device );
+    if ( deviceInfo )
     {
         // Creating a partition table wipes all the disk, so there is no need to
         // keep previous changes
-        info->forgetChanges();
+        deviceInfo->forgetChanges();
 
         OperationHelper helper( partitionModelForDevice( device ), this );
-        CreatePartitionTableJob* job = new CreatePartitionTableJob( device, type );
-        job->updatePreview();
-        info->jobs << Calamares::job_ptr( job );
+        deviceInfo->makeJob< CreatePartitionTableJob >( type );
     }
 }
 
 void
 PartitionCoreModule::createPartition( Device* device, Partition* partition, PartitionTable::Flags flags )
 {
-    auto deviceInfo = infoForDevice( device );
+    auto* deviceInfo = infoForDevice( device );
     Q_ASSERT( deviceInfo );
 
     OperationHelper helper( partitionModelForDevice( device ), this );
-    CreatePartitionJob* job = new CreatePartitionJob( device, partition );
-    job->updatePreview();
-
-    deviceInfo->jobs << Calamares::job_ptr( job );
+    deviceInfo->makeJob< CreatePartitionJob >( partition );
 
     if ( flags != KPM_PARTITION_FLAG( None ) )
     {
-        SetPartFlagsJob* fJob = new SetPartFlagsJob( device, partition, flags );
-        deviceInfo->jobs << Calamares::job_ptr( fJob );
+        deviceInfo->makeJob< SetPartFlagsJob >( partition, flags );
         PartitionInfo::setFlags( partition, flags );
     }
 }
@@ -327,49 +377,39 @@ PartitionCoreModule::createVolumeGroup( QString& vgName, QVector< const Partitio
         vgName.append( '_' );
     }
 
-    CreateVolumeGroupJob* job = new CreateVolumeGroupJob( vgName, pvList, peSize );
-    job->updatePreview();
-
     LvmDevice* device = new LvmDevice( vgName );
-
     for ( const Partition* p : pvList )
     {
         device->physicalVolumes() << p;
     }
 
     DeviceInfo* deviceInfo = new DeviceInfo( device );
-
     deviceInfo->partitionModel->init( device, osproberEntries() );
-
     m_deviceModel->addDevice( device );
-
     m_deviceInfos << deviceInfo;
-    deviceInfo->jobs << Calamares::job_ptr( job );
 
+    deviceInfo->makeJob< CreateVolumeGroupJob >( vgName, pvList, peSize );
     refreshAfterModelChange();
 }
 
 void
 PartitionCoreModule::resizeVolumeGroup( LvmDevice* device, QVector< const Partition* >& pvList )
 {
-    DeviceInfo* deviceInfo = infoForDevice( device );
+    auto* deviceInfo = infoForDevice( device );
     Q_ASSERT( deviceInfo );
-
-    ResizeVolumeGroupJob* job = new ResizeVolumeGroupJob( device, pvList );
-
-    deviceInfo->jobs << Calamares::job_ptr( job );
-
+    deviceInfo->makeJob< ResizeVolumeGroupJob >( device, pvList );
     refreshAfterModelChange();
 }
 
 void
 PartitionCoreModule::deactivateVolumeGroup( LvmDevice* device )
 {
-    DeviceInfo* deviceInfo = infoForDevice( device );
+    auto* deviceInfo = infoForDevice( device );
     Q_ASSERT( deviceInfo );
 
     deviceInfo->isAvailable = false;
 
+    // TODO: this leaks
     DeactivateVolumeGroupJob* job = new DeactivateVolumeGroupJob( device );
 
     // DeactivateVolumeGroupJob needs to be immediately called
@@ -381,20 +421,16 @@ PartitionCoreModule::deactivateVolumeGroup( LvmDevice* device )
 void
 PartitionCoreModule::removeVolumeGroup( LvmDevice* device )
 {
-    DeviceInfo* deviceInfo = infoForDevice( device );
+    auto* deviceInfo = infoForDevice( device );
     Q_ASSERT( deviceInfo );
-
-    RemoveVolumeGroupJob* job = new RemoveVolumeGroupJob( device );
-
-    deviceInfo->jobs << Calamares::job_ptr( job );
-
+    deviceInfo->makeJob< RemoveVolumeGroupJob >( device );
     refreshAfterModelChange();
 }
 
 void
 PartitionCoreModule::deletePartition( Device* device, Partition* partition )
 {
-    auto deviceInfo = infoForDevice( device );
+    auto* deviceInfo = infoForDevice( device );
     Q_ASSERT( deviceInfo );
 
     OperationHelper helper( partitionModelForDevice( device ), this );
@@ -417,7 +453,7 @@ PartitionCoreModule::deletePartition( Device* device, Partition* partition )
         }
     }
 
-    Calamares::JobList& jobs = deviceInfo->jobs;
+    const Calamares::JobList& jobs = deviceInfo->jobs();
     if ( partition->state() == KPM_PARTITION_STATE( New ) )
     {
         // First remove matching SetPartFlagsJobs
@@ -472,44 +508,36 @@ PartitionCoreModule::deletePartition( Device* device, Partition* partition )
                 ++it;
             }
         }
-        DeletePartitionJob* job = new DeletePartitionJob( device, partition );
-        job->updatePreview();
-        jobs << Calamares::job_ptr( job );
+
+        deviceInfo->makeJob< DeletePartitionJob >( partition );
     }
 }
 
 void
 PartitionCoreModule::formatPartition( Device* device, Partition* partition )
 {
-    auto deviceInfo = infoForDevice( device );
+    auto* deviceInfo = infoForDevice( device );
     Q_ASSERT( deviceInfo );
     OperationHelper helper( partitionModelForDevice( device ), this );
-
-    FormatPartitionJob* job = new FormatPartitionJob( device, partition );
-    deviceInfo->jobs << Calamares::job_ptr( job );
+    deviceInfo->makeJob< FormatPartitionJob >( partition );
 }
 
 void
 PartitionCoreModule::resizePartition( Device* device, Partition* partition, qint64 first, qint64 last )
 {
-    auto deviceInfo = infoForDevice( device );
+    auto* deviceInfo = infoForDevice( device );
     Q_ASSERT( deviceInfo );
     OperationHelper helper( partitionModelForDevice( device ), this );
-
-    ResizePartitionJob* job = new ResizePartitionJob( device, partition, first, last );
-    job->updatePreview();
-    deviceInfo->jobs << Calamares::job_ptr( job );
+    deviceInfo->makeJob< ResizePartitionJob >( partition, first, last );
 }
 
 void
 PartitionCoreModule::setPartitionFlags( Device* device, Partition* partition, PartitionTable::Flags flags )
 {
-    auto deviceInfo = infoForDevice( device );
+    auto* deviceInfo = infoForDevice( device );
     Q_ASSERT( deviceInfo );
     OperationHelper( partitionModelForDevice( device ), this );
-
-    SetPartFlagsJob* job = new SetPartFlagsJob( device, partition, flags );
-    deviceInfo->jobs << Calamares::job_ptr( job );
+    deviceInfo->makeJob< SetPartFlagsJob >( partition, flags );
     PartitionInfo::setFlags( partition, flags );
 }
 
@@ -542,7 +570,7 @@ PartitionCoreModule::jobs() const
 
     for ( auto info : m_deviceInfos )
     {
-        lst << info->jobs;
+        lst << info->jobs();
         devices << info->device.data();
     }
     lst << Calamares::job_ptr( new FillGlobalStorageJob( devices, m_bootLoaderInstallPath ) );
@@ -596,7 +624,7 @@ PartitionCoreModule::dumpQueue() const
     for ( auto info : m_deviceInfos )
     {
         cDebug() << "## Device:" << info->device->name();
-        for ( auto job : info->jobs )
+        for ( const auto& job : info->jobs() )
         {
             cDebug() << "-" << job->prettyName();
         }
@@ -736,7 +764,7 @@ PartitionCoreModule::scanForLVMPVs()
 
     for ( DeviceInfo* d : m_deviceInfos )
     {
-        for ( auto job : d->jobs )
+        for ( const auto& job : d->jobs() )
         {
             // Including new LVM PVs
             CreatePartitionJob* partJob = dynamic_cast< CreatePartitionJob* >( job.data() );
@@ -963,9 +991,9 @@ PartitionCoreModule::revertAllDevices()
         {
             ( *it )->isAvailable = true;
 
-            if ( !( *it )->jobs.empty() )
+            if ( !( *it )->jobs().empty() )
             {
-                CreateVolumeGroupJob* vgJob = dynamic_cast< CreateVolumeGroupJob* >( ( *it )->jobs[ 0 ].data() );
+                CreateVolumeGroupJob* vgJob = dynamic_cast< CreateVolumeGroupJob* >( ( *it )->jobs().first().data() );
 
                 if ( vgJob )
                 {