Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DRAFT Custom model interface #1917

Draft
wants to merge 3 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 16 additions & 5 deletions src/gui/keywordWidgets/expressionVariableVector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,19 @@
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
connect(&variableModel_, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &, const QVector<int> &)), this,
SLOT(modelDataChanged(const QModelIndex &, const QModelIndex &)));
SLOT(variableDataChanged(const QModelIndex &, const QModelIndex &)));
connect(ui_.VariablesTable->selectionModel(), SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)),
this, SLOT(variableSelectionChanged(const QItemSelection &, const QItemSelection &)));

// Add suitable delegate to the table
ui_.VariablesTable->setItemDelegateForColumn(2, new ExponentialSpinDelegate(this));
Expand All @@ -31,13 +32,23 @@ ExpressionVariableVectorKeywordWidget::ExpressionVariableVectorKeywordWidget(QWi
*/

// Variable data changed
void ExpressionVariableVectorKeywordWidget::modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
void ExpressionVariableVectorKeywordWidget::variableDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
{
if (refreshing_)
return;

Q_EMIT(keywordDataChanged(keyword_->editSignals()));
}

void ExpressionVariableVectorKeywordWidget::variableSelectionChanged(const QItemSelection &current,
const QItemSelection &previous)
{
ui_.RemoveVariableButton->setEnabled(current.empty());
}

void ExpressionVariableVectorKeywordWidget::ui_AddVariableButton_clicked(bool checked) {}

void ExpressionVariableVectorKeywordWidget::ui_RemoveVariableButton_clicked(bool checked) {}

// Update value displayed in widget
void ExpressionVariableVectorKeywordWidget::updateValue(const Flags<DissolveSignals::DataMutations> &mutationFlags) {}
7 changes: 5 additions & 2 deletions src/gui/keywordWidgets/expressionVariableVector.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,13 @@ class ExpressionVariableVectorKeywordWidget : public QWidget, public KeywordWidg
// Main form declaration
Ui::ExpressionVariableVectorWidget ui_;
// Model for table
ExpressionVariableVectorModel variableModel_;
DataTableModelInterface variableModel_;

private Q_SLOTS:
void modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
void variableDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
void variableSelectionChanged(const QItemSelection &current, const QItemSelection &previous);
void ui_AddVariableButton_clicked(bool checked);
void ui_RemoveVariableButton_clicked(bool checked);

Q_SIGNALS:
// Keyword data changed
Expand Down
81 changes: 79 additions & 2 deletions src/gui/keywordWidgets/expressionVariableVector.ui
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>194</width>
<height>81</height>
<height>99</height>
</rect>
</property>
<property name="font">
Expand Down Expand Up @@ -53,8 +53,85 @@
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="spacing">
<number>4</number>
</property>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QToolButton" name="RemoveVariableButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Remove</string>
</property>
<property name="icon">
<iconset resource="../main.qrc">
<normaloff>:/general/icons/remove.svg</normaloff>:/general/icons/remove.svg</iconset>
</property>
<property name="iconSize">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="AddVariableButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Add</string>
</property>
<property name="icon">
<iconset resource="../main.qrc">
<normaloff>:/general/icons/add.svg</normaloff>:/general/icons/add.svg</iconset>
</property>
<property name="iconSize">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<resources>
<include location="../main.qrc"/>
</resources>
<connections/>
</ui>
144 changes: 65 additions & 79 deletions src/gui/models/expressionVariableVectorModel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,122 +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,
const 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)
// Set new value
bool success = false;
switch (dataModel_.propertyType(index.column()))
{
// 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());
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;
}
else if (index.column() == 2)

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

return success;
}

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

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

Q_EMIT dataChanged(index, index);
beginRemoveRows(parent, row, row);
// ranges_->get().erase(ranges_->get().begin() + row);
endRemoveRows();
return true;
}
24 changes: 10 additions & 14 deletions src/gui/models/expressionVariableVectorModel.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,30 @@

#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)
const ProcedureNode *parentNode_{nullptr};

public:
// Set source variable data
void setData(std::vector<std::shared_ptr<ExpressionVariable>> &variables, const 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;
Qt::ItemFlags flags(const QModelIndex &index) const override;
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
QVariant data(const QModelIndex &index, int role) const override;
bool setData(const QModelIndex &index, const QVariant &value, int role) override;
bool insertRows(int row, int count, const QModelIndex &parent) override;
bool removeRows(int row, int count, const QModelIndex &parent) override;
};
Loading
Loading