Skip to content

Commit

Permalink
All working so far.
Browse files Browse the repository at this point in the history
  • Loading branch information
trisyoungs committed Jul 9, 2024
1 parent ac9cb7e commit 84f684c
Show file tree
Hide file tree
Showing 6 changed files with 233 additions and 144 deletions.
7 changes: 3 additions & 4 deletions src/gui/keywordWidgets/expressionVariableVector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,12 @@
ExpressionVariableVectorKeywordWidget::ExpressionVariableVectorKeywordWidget(QWidget *parent,
ExpressionVariableVectorKeyword *keyword,
const CoreData &coreData)
: QWidget(parent), KeywordWidgetBase(coreData), keyword_(keyword)
: QWidget(parent), KeywordWidgetBase(coreData), keyword_(keyword), variableModel_(keyword->dataModel())
{
// Create and set up the UI for our widget
ui_.setupUi(this);

// Set up model
variableModel_.setData(keyword->data(), keyword->parentNode());
// Set model
ui_.VariablesTable->setModel(&variableModel_);

// Connect signals / slots
Expand Down Expand Up @@ -47,7 +46,7 @@ void ExpressionVariableVectorKeywordWidget::variableSelectionChanged(const QItem
ui_.RemoveVariableButton->setEnabled(current.empty());
}

void ExpressionVariableVectorKeywordWidget::ui_AddVariableButton_clicked(bool checked) { }
void ExpressionVariableVectorKeywordWidget::ui_AddVariableButton_clicked(bool checked) {}

void ExpressionVariableVectorKeywordWidget::ui_RemoveVariableButton_clicked(bool checked) {}

Expand Down
2 changes: 1 addition & 1 deletion src/gui/keywordWidgets/expressionVariableVector.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class ExpressionVariableVectorKeywordWidget : public QWidget, public KeywordWidg
// Main form declaration
Ui::ExpressionVariableVectorWidget ui_;
// Model for table
ExpressionVariableVectorModel variableModel_;
DataTableModelInterface variableModel_;

private Q_SLOTS:
void variableDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
Expand Down
135 changes: 49 additions & 86 deletions src/gui/models/expressionVariableVectorModel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,145 +4,108 @@
#include "gui/models/expressionVariableVectorModel.h"
#include "procedure/nodes/node.h"

// Set source variable data
void ExpressionVariableVectorModel::setData(std::vector<std::shared_ptr<ExpressionVariable>> &variables,
ProcedureNode *parentNode)
{
beginResetModel();
variables_ = variables;
parentNode_ = parentNode;
endResetModel();
}
DataTableModelInterface::DataTableModelInterface(DataModelBase &dataModel) : dataModel_(dataModel) {}

int ExpressionVariableVectorModel::rowCount(const QModelIndex &parent) const
int DataTableModelInterface::rowCount(const QModelIndex &parent) const
{
if (parent.isValid())
return 0;
return variables_ ? variables_->get().size() : 0;
return dataModel_.nChildren(parent.row(), parent.column());
}
int ExpressionVariableVectorModel::columnCount(const QModelIndex &parent) const

int DataTableModelInterface::columnCount(const QModelIndex &parent) const
{
if (parent.isValid())
return 0;
return 3;
return dataModel_.nProperties(parent.row(), parent.column());
}

Qt::ItemFlags ExpressionVariableVectorModel::flags(const QModelIndex &index) const
Qt::ItemFlags DataTableModelInterface::flags(const QModelIndex &index) const
{
// TODO
if (index.column() == 1)
return Qt::ItemIsSelectable | Qt::ItemIsEnabled;
else
return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable;
}

QVariant ExpressionVariableVectorModel::headerData(int section, Qt::Orientation orientation, int role) const
QVariant DataTableModelInterface::headerData(int section, Qt::Orientation orientation, int role) const
{
if (role != Qt::DisplayRole)
if (role != Qt::DisplayRole || orientation != Qt::Horizontal)
return {};

if (orientation == Qt::Horizontal)
switch (section)
{
case 0:
return "Name";
case 1:
return "Type";
case 2:
return "Value";
default:
return {};
}

return {};
return QString::fromStdString(dataModel_.propertyName(section));
}

// Bond model
QVariant ExpressionVariableVectorModel::data(const QModelIndex &index, int role) const
QVariant DataTableModelInterface::data(const QModelIndex &index, int role) const
{
if (!index.isValid() || !variables_)
return {};

auto &vars = variables_->get();

if (index.row() >= vars.size() || index.row() < 0)
return {};

if (role != Qt::DisplayRole && role != Qt::EditRole)
return {};

auto &var = vars[index.row()];
// Get the specified data property
auto property = dataModel_.getProperty(index.row(), index.column());

switch (index.column())
switch (property.type())
{
// Name
case 0:
return QString::fromStdString(std::string(var->baseName()));
case 1:
return var->value().type() == ExpressionValue::ValueType::Integer ? "Int" : "Real";
case 2:
return QString::fromStdString(var->value().asString());
case (PropertyType::Invalid):
return {};
case (PropertyType::Integer):
return property.intValue();
case (PropertyType::Double):
return property.doubleValue();
case (PropertyType::String):
return QString::fromStdString(property.stringValue());
default:
return {};
}

return {};
}

bool ExpressionVariableVectorModel::setData(const QModelIndex &index, const QVariant &value, int role)
bool DataTableModelInterface::setData(const QModelIndex &index, const QVariant &value, int role)
{
if (role != Qt::EditRole || !variables_ || index.column() == 1)
if (role != Qt::EditRole || dataModel_.isPropertyFlagSet(index.column(), PropertyFlag::ReadOnly))
return false;

auto &var = variables_->get()[index.row()];

if (index.column() == 0)
{
// Name - must check for existing var in scope with the same name
auto p = parentNode_->getParameterInScope(value.toString().toStdString());
if (p && p != var)
return false;
var->setBaseName(value.toString().toStdString());
}
else if (index.column() == 2)
// Set new value
bool success = false;
switch (dataModel_.propertyType(index.column()))
{
// Value - need to check type (int vs double)
auto varValue = value.toString().toStdString();
bool isFloatingPoint = false;
if (DissolveSys::isNumber(varValue, isFloatingPoint))
{
if (isFloatingPoint)
var->setValue(value.toDouble());
else
var->setValue(value.toInt());
}
else
return Messenger::error("Value '{}' provided for variable '{}' doesn't appear to be a number.\n", varValue,
var->baseName());
case (PropertyType::Integer):
success = dataModel_.setProperty(index.row(), index.column(), DataItemValue(value.toInt()));
break;
case (PropertyType::Double):
success = dataModel_.setProperty(index.row(), index.column(), DataItemValue(value.toDouble()));
break;
case (PropertyType::String):
success = dataModel_.setProperty(index.row(), index.column(), DataItemValue(value.toString().toStdString()));
break;
default:
break;
}

Q_EMIT dataChanged(index, index);
return true;
if (success)
Q_EMIT dataChanged(index, index);

return success;
}

bool ExpressionVariableVectorModel::insertRows(int row, int count, const QModelIndex &parent)
bool DataTableModelInterface::insertRows(int row, int count, const QModelIndex &parent)
{
// TODO
Q_UNUSED(count);
beginInsertRows(parent, row, row);
parentNode_->addParameter("NewParameter", 0.0, row);
// parentNode_->addParameter("NewParameter", 0.0, row);
endInsertRows();
return true;
}

bool ExpressionVariableVectorModel::removeRows(int row, int count, const QModelIndex &parent)
bool DataTableModelInterface::removeRows(int row, int count, const QModelIndex &parent)
{
// TODO
Q_UNUSED(count);
if (row >= rowCount(parent) || row < 0)
{
return false;
}

beginRemoveRows(parent, row, row);
// ranges_->get().erase(ranges_->get().begin() + row);
// ranges_->get().erase(ranges_->get().begin() + row);
endRemoveRows();
return true;
}
22 changes: 8 additions & 14 deletions src/gui/models/expressionVariableVectorModel.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,23 @@

#pragma once

#include "expression/variable.h"
#include "keywords/expressionVariableVector.h"
#include "templates/optionalRef.h"
#include <QAbstractTableModel>
#include <QModelIndex>
#include <vector>

// Forward Declarations
class ProcedureNode;

// Expression Variable Vector Model
class ExpressionVariableVectorModel : public QAbstractTableModel
// Qt Interface to DataTableModel
class DataTableModelInterface : public QAbstractTableModel
{
Q_OBJECT

private:
// Source variable data
OptionalReferenceWrapper<std::vector<std::shared_ptr<ExpressionVariable>>> variables_;
// Parent procedure node (to enable parameter search)
ProcedureNode *parentNode_{nullptr};

public:
// Set source variable data
void setData(std::vector<std::shared_ptr<ExpressionVariable>> &variables, ProcedureNode *parentNode);
DataTableModelInterface(DataModelBase &dataModel);

private:
// Model with which to interface
DataModelBase &dataModel_;

int rowCount(const QModelIndex &parent) const override;
int columnCount(const QModelIndex &parent) const override;
Expand Down
60 changes: 56 additions & 4 deletions src/keywords/expressionVariableVector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,64 @@ enum ExpressionVariableProperties
Type,
Value
};
std::vector<DataItemProperty> expressionVariableProperties = {{ExpressionVariableProperties::Name, "Name", PropertyType::String, false},
{ExpressionVariableProperties::Type, "Type", PropertyType::String, false},
{ExpressionVariableProperties::Value, "Value", PropertyType::String, false}
};
std::vector<DataItemProperty> expressionVariableProperties = {
{ExpressionVariableProperties::Name, "Name", PropertyType::String, {}},
{ExpressionVariableProperties::Type, "Type", PropertyType::String, {PropertyFlag::ReadOnly}},
{ExpressionVariableProperties::Value, "Value", PropertyType::String, {}}};

ExpressionVariableVectorKeyword::ExpressionVariableVectorKeyword(std::vector<std::shared_ptr<ExpressionVariable>> &data,
ProcedureNode *parentNode)
: KeywordBase(typeid(this)), data_(data), parentNode_(parentNode), dataModel_(data_, expressionVariableProperties)
{
dataModel_.setPropertyFunctions(
[&](const std::shared_ptr<ExpressionVariable> &var, int propertyIndex)
{
switch (propertyIndex)
{
case (ExpressionVariableProperties::Name):
return DataItemValue(var->baseName());
case (ExpressionVariableProperties::Type):
return DataItemValue(std::string(var->value().type() == ExpressionValue::ValueType::Integer ? "Int" : "Real"));
case (ExpressionVariableProperties::Value):
return DataItemValue(var->value().asString());
default:
return DataItemValue();
}
},
[&](std::shared_ptr<ExpressionVariable> &var, int propertyIndex, const DataItemValue &newValue)
{
switch (propertyIndex)
{
case (ExpressionVariableProperties::Name):
{
// Must check for existing var in scope with the same name
auto p = parentNode_->getParameter(newValue.stringValue());
if (p && p != var)
return false;
var->setBaseName(newValue.stringValue());
}
break;
case (ExpressionVariableProperties::Value):
{
// Value - need to check type (int vs double)
bool isFloatingPoint = false;
if (DissolveSys::isNumber(newValue.stringValue(), isFloatingPoint))
{
if (isFloatingPoint)
var->setValue(std::stod(newValue.stringValue()));
else
var->setValue(std::stoi(newValue.stringValue()));
}
else
return Messenger::error("Value '{}' provided for variable '{}' doesn't appear to be a number.\n",
newValue.stringValue(), var->baseName());
}
break;
default:
return false;
}
return true;
});
}

/*
Expand All @@ -33,6 +82,9 @@ ExpressionVariableVectorKeyword::ExpressionVariableVectorKeyword(std::vector<std
std::vector<std::shared_ptr<ExpressionVariable>> &ExpressionVariableVectorKeyword::data() { return data_; }
const std::vector<std::shared_ptr<ExpressionVariable>> &ExpressionVariableVectorKeyword::data() const { return data_; }

// Return data model
DataTableModel<std::shared_ptr<ExpressionVariable>> &ExpressionVariableVectorKeyword::dataModel() { return dataModel_; }

// Return parent ProcedureNode
ProcedureNode *ExpressionVariableVectorKeyword::parentNode() { return parentNode_; }
const ProcedureNode *ExpressionVariableVectorKeyword::parentNode() const { return parentNode_; }
Expand Down
Loading

0 comments on commit 84f684c

Please sign in to comment.