return optional from model traverse callback

Allows callers to stop traversing model when they are done processing
This commit is contained in:
Jussi Kuokkanen 2023-08-31 20:38:22 +03:00
parent c67eaa00f2
commit b6ed9b2e7c
3 changed files with 15 additions and 13 deletions

View File

@ -20,16 +20,17 @@ QVariant fromAssignmentArgument(TuxClocker::Device::AssignmentArgument arg) {
return QVariant{}; return QVariant{};
} }
using ModelTraverseCallback =
std::function<QModelIndex(QAbstractItemModel *, const QModelIndex &, int)>;
void traverseModel( void traverseModel(
const ModelTraverseCallback &cb, QAbstractItemModel *model, const QModelIndex &parent) { const ModelTraverseCallback &cb, QAbstractItemModel *model, const QModelIndex &parent) {
for (int i = 0; i < model->rowCount(parent); i++) { for (int i = 0; i < model->rowCount(parent); i++) {
auto nextOpt = cb(model, parent, i);
if (!nextOpt.has_value())
// Returning nothing is used as indication we should stop traversing
return;
// We get the next index we should traverse, and the funtion does // We get the next index we should traverse, and the funtion does
// its thing with the model and index // its thing with the model and index
auto nextIndex = cb(model, parent, i); auto nextIndex = nextOpt.value();
if (model->hasChildren(nextIndex)) { if (model->hasChildren(nextIndex)) {
traverseModel(cb, model, nextIndex); traverseModel(cb, model, nextIndex);
} }

View File

@ -5,7 +5,7 @@
namespace Utils { namespace Utils {
using ModelTraverseCallback = using ModelTraverseCallback =
std::function<QModelIndex(QAbstractItemModel *, const QModelIndex &, int)>; std::function<std::optional<QModelIndex>(QAbstractItemModel *, const QModelIndex &, int)>;
void traverseModel( void traverseModel(
const ModelTraverseCallback &, QAbstractItemModel *, const QModelIndex &parent = QModelIndex()); const ModelTraverseCallback &, QAbstractItemModel *, const QModelIndex &parent = QModelIndex());

View File

@ -162,28 +162,29 @@ void DeviceModelDelegate::setAssignableData(
} }
bool DeviceModelDelegate::subtreeHasAssignableDefaults( bool DeviceModelDelegate::subtreeHasAssignableDefaults(
QAbstractItemModel *model, const QModelIndex &item) { QAbstractItemModel *model, const QModelIndex &index) {
QSettings settings{"tuxclocker"}; QSettings settings{"tuxclocker"};
settings.beginGroup("assignableDefaults"); settings.beginGroup("assignableDefaults");
bool hasDefaults = false; bool hasDefaults = false;
auto cb = [&settings, &hasDefaults]( auto cb = [&settings, &hasDefaults](QAbstractItemModel *model, const QModelIndex &index,
QAbstractItemModel *model, const QModelIndex &index, int row) { int row) -> std::optional<const QModelIndex> {
auto ifaceIndex = model->index(row, DeviceModel::InterfaceColumn, index); auto ifaceIndex = model->index(row, DeviceModel::InterfaceColumn, index);
auto assProxyV = ifaceIndex.data(DeviceModel::AssignableProxyRole); auto assProxyV = ifaceIndex.data(DeviceModel::AssignableProxyRole);
qDebug() << model->index(row, DeviceModel::NameColumn, index).data(); auto name = model->index(row, DeviceModel::NameColumn, index).data();
if (assProxyV.isValid()) { if (assProxyV.isValid()) {
auto nodePath = qvariant_cast<AssignableProxy *>(assProxyV)->dbusPath(); auto nodePath = qvariant_cast<AssignableProxy *>(assProxyV)->dbusPath();
if (settings.contains(nodePath.replace('/', '-'))) { if (settings.contains(nodePath.replace('/', '-'))) {
// TODO: break out of the function here // This stops traversing model
hasDefaults = true; hasDefaults = true;
return std::nullopt;
} }
} }
return model->index(row, DeviceModel::NameColumn, index); return model->index(row, DeviceModel::NameColumn, index);
}; };
Utils::traverseModel(cb, model); auto nameIndex = model->index(index.row(), DeviceModel::NameColumn, index.parent());
Utils::traverseModel(cb, model, nameIndex);
return hasDefaults; return hasDefaults;
} }