From d0276fd25fde2717e81ac02c56454847ad175306 Mon Sep 17 00:00:00 2001
From: Adriaan de Groot <groot@kde.org>
Date: Tue, 25 May 2021 13:05:45 +0200
Subject: [PATCH] [partition] Look up bootloader by name, method

The bootloader model knows about both rows and
devices, so we can look up both at once. The
existing implementation as a non-member was rather
sketchy and wasn't used except as support for
restoreSelectedBootLoader().
---
 .../partition/core/BootLoaderModel.cpp        | 46 +++++++++++++------
 src/modules/partition/core/BootLoaderModel.h  | 15 +++---
 2 files changed, 39 insertions(+), 22 deletions(-)

diff --git a/src/modules/partition/core/BootLoaderModel.cpp b/src/modules/partition/core/BootLoaderModel.cpp
index 08b0283b3..fd66c8514 100644
--- a/src/modules/partition/core/BootLoaderModel.cpp
+++ b/src/modules/partition/core/BootLoaderModel.cpp
@@ -18,6 +18,7 @@
 
 // KPMcore
 #include <kpmcore/core/device.h>
+#include <kpmcore/core/partition.h>
 
 #include <QComboBox>
 
@@ -148,28 +149,39 @@ BootLoaderModel::data( const QModelIndex& index, int role ) const
     return QStandardItemModel::data( index, role );
 }
 
-namespace Calamares
-{
-int
-findBootloader( const QAbstractItemModel* model, const QString& path )
+std::pair< int, Device* >
+BootLoaderModel::findBootLoader( const QString& path ) const
 {
-    for ( int i = 0; i < model->rowCount(); ++i )
+    int r = 0;
+    for ( Device* d : m_devices )
     {
-        const auto index = model->index( i, 0, QModelIndex() );
-        if ( !index.isValid() )
+        if ( d && d->deviceNode() == path )
         {
-            continue;
+            return std::make_pair( r, d );
         }
-        QVariant var = model->data( index, BootLoaderModel::BootLoaderPathRole );
-        if ( var.isValid() && var.toString() == path )
+        r++;
+    }
+
+    Partition* partition = KPMHelpers::findPartitionByMountPoint( m_devices, path );
+    if ( partition )
+    {
+        const QString partition_device_path = partition->deviceNode();
+        r = 0;
+        for ( Device* d : m_devices )
         {
-            return i;
+            if ( d && d->deviceNode() == partition_device_path )
+            {
+                return std::make_pair( r, d );
+            }
+            r++;
         }
     }
-
-    return -1;
+    return std::make_pair( -1, nullptr );
 }
 
+
+namespace Calamares
+{
 void
 restoreSelectedBootLoader( QComboBox& combo, const QString& path )
 {
@@ -180,12 +192,16 @@ restoreSelectedBootLoader( QComboBox& combo, const QString& path )
         return;
     }
 
-    int r = -1;
     if ( path.isEmpty() )
     {
+        cDebug() << "No path to restore, choosing default";
         combo.setCurrentIndex( 0 );
+        return;
     }
-    else if ( ( r = findBootloader( model, path ) ) >= 0 )
+
+    const BootLoaderModel* bmodel = qobject_cast< const BootLoaderModel* >( model );
+    int r = bmodel ? bmodel->findBootLoader( path ).first : -1;
+    if ( r >= 0 )
     {
         combo.setCurrentIndex( r );
     }
diff --git a/src/modules/partition/core/BootLoaderModel.h b/src/modules/partition/core/BootLoaderModel.h
index 9b1a651e4..e640d4d7c 100644
--- a/src/modules/partition/core/BootLoaderModel.h
+++ b/src/modules/partition/core/BootLoaderModel.h
@@ -47,6 +47,14 @@ public:
 
     QVariant data( const QModelIndex& index, int role = Qt::DisplayRole ) const override;
 
+    /** @brief Looks up a boot-loader by device-name @p path (e.g. /dev/sda)
+    *
+    * Returns a row number (index) in the model and a Device*: if there **is** a
+    * device for the given @p path, index will be in range of the model and
+    * Device* non-null. Returns (-1, nullptr) otherwise.
+    */
+    std::pair< int, Device* > findBootLoader( const QString& path ) const;
+
 private:
     DeviceList m_devices;
     mutable QMutex m_lock;
@@ -57,13 +65,6 @@ private:
 
 namespace Calamares
 {
-/** @brief Returns the row number of boot-loader @p path (e.g. /dev/sda)
- *
- * Assuming the @p model is a BootLoaderModel, will return a row number
- * in the model. Returns -1 otherwise.
- */
-int findBootloader( const QAbstractItemModel* model, const QString& path );
-
 /** @brief Tries to set @p path as selected item in @p combo
  *
  * Matches a boot-loader install path (e.g. /dev/sda) with a model