From 52a8568bf64a839e6779ddee189fe4896968597e Mon Sep 17 00:00:00 2001 From: Adam Washington Date: Wed, 12 Nov 2025 10:02:12 +0000 Subject: [PATCH 01/31] Initial BROKEN Species Node --- src/nodes/CMakeLists.txt | 1 + src/nodes/atomicSpecies.cpp | 1 - src/nodes/atomicSpecies.h | 2 -- src/nodes/registry.cpp | 2 ++ src/nodes/species.cpp | 35 ++++++++++++++++++++++++++++++++ src/nodes/species.h | 40 +++++++++++++++++++++++++++++++++++++ tests/nodes/CMakeLists.txt | 1 + tests/nodes/species.cpp | 34 +++++++++++++++++++++++++++++++ 8 files changed, 113 insertions(+), 3 deletions(-) create mode 100644 src/nodes/species.cpp create mode 100644 src/nodes/species.h create mode 100644 tests/nodes/species.cpp diff --git a/src/nodes/CMakeLists.txt b/src/nodes/CMakeLists.txt index f26e9a23f0..ac507e9f6d 100644 --- a/src/nodes/CMakeLists.txt +++ b/src/nodes/CMakeLists.txt @@ -4,6 +4,7 @@ file( "./*.cpp" ) + file( GLOB_RECURSE node_headers RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} diff --git a/src/nodes/atomicSpecies.cpp b/src/nodes/atomicSpecies.cpp index 75ceb481f0..c8b5426178 100644 --- a/src/nodes/atomicSpecies.cpp +++ b/src/nodes/atomicSpecies.cpp @@ -2,7 +2,6 @@ // Copyright (c) 2025 Team Dissolve and contributors #include "atomicSpecies.h" -#include "dissolve.h" AtomicSpeciesNode::AtomicSpeciesNode(Graph *parentGraph, Elements::Element Z) : Node(parentGraph) { diff --git a/src/nodes/atomicSpecies.h b/src/nodes/atomicSpecies.h index 3c707ca193..4620335c0f 100644 --- a/src/nodes/atomicSpecies.h +++ b/src/nodes/atomicSpecies.h @@ -4,9 +4,7 @@ #pragma once #include "classes/species.h" -#include "math/vector3.h" #include "nodes/node.h" -#include // AtomicSpecies Node class AtomicSpeciesNode : public Node diff --git a/src/nodes/registry.cpp b/src/nodes/registry.cpp index acf303a2f2..c0014e55bc 100644 --- a/src/nodes/registry.cpp +++ b/src/nodes/registry.cpp @@ -22,6 +22,7 @@ #include "nodes/multiply.h" #include "nodes/neutronSQ/neutronSQ.h" #include "nodes/numberNode.h" +#include "nodes/species.h" #include "nodes/sq/sq.h" #include "nodes/subtract.h" #include "nodes/vec3Assembly.h" @@ -63,6 +64,7 @@ void NodeRegistry::instantiateNodeProducers() {"Multiply", makeDerivedNode()}, {"NeutronSQ", makeDerivedNode()}, {"Number", makeDerivedNode()}, + {"Species", makeDerivedNode()}, {"SQ", makeDerivedNode()}, {"Subtract", makeDerivedNode()}, {"Vec3Assembly", makeDerivedNode()}, diff --git a/src/nodes/species.cpp b/src/nodes/species.cpp new file mode 100644 index 0000000000..fe1abf2d21 --- /dev/null +++ b/src/nodes/species.cpp @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright (c) 2025 Team Dissolve and contributors + +#include +#include +#include +#include "species.h" +#include "classes/coreData.h" +#include "nodes/constants.h" + +SpeciesNode::SpeciesNode(Graph *parentGraph) : Node(parentGraph) +{ + addOption("Definition", "TOML that defines the species", definition_); + addPointerOutput("Species", "Created species", species_); +} + +std::string_view SpeciesNode::type() const { return "Species"; } + +std::string_view SpeciesNode::summary() const { return "Produce a species"; } + +NodeConstants::ProcessResult SpeciesNode::process() +{ + CoreData coreData; + try { + std::istringstream stream(definition_); + SerialisedValue node = toml::parse(stream); + species_.deserialise(node, coreData); + atomTypes_ = coreData.atomTypes(); + return NodeConstants::ProcessResult::Success; + } + catch(...) + { + return NodeConstants::ProcessResult::Failed; + } +} diff --git a/src/nodes/species.h b/src/nodes/species.h new file mode 100644 index 0000000000..cdba74d33f --- /dev/null +++ b/src/nodes/species.h @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright (c) 2025 Team Dissolve and contributors + +#pragma once + +#include "classes/species.h" +#include "nodes/node.h" + +// Species Node +class SpeciesNode : public Node +{ + public: + SpeciesNode(Graph *parentGraph); + ~SpeciesNode() override = default; + + /* + * Definition + */ + public: + std::string_view type() const override; + std::string_view summary() const override; + + /* + * Data + */ + private: + // TOML Definition + std::string definition_; + // Species object + Species species_; + // Atom Types owned by the node + std::vector> atomTypes_; + + /* + * Processing + */ + private: + // Run main processing + NodeConstants::ProcessResult process() override; +}; diff --git a/tests/nodes/CMakeLists.txt b/tests/nodes/CMakeLists.txt index 3a77d1d055..f9b8f26f42 100644 --- a/tests/nodes/CMakeLists.txt +++ b/tests/nodes/CMakeLists.txt @@ -4,3 +4,4 @@ dissolve_add_test(SRC graph_argon.cpp) dissolve_add_test(SRC number.cpp) dissolve_add_test(SRC parameters.cpp) dissolve_add_test(SRC subGraph.cpp) +dissolve_add_test(SRC species.cpp) diff --git a/tests/nodes/species.cpp b/tests/nodes/species.cpp new file mode 100644 index 0000000000..8c734492f4 --- /dev/null +++ b/tests/nodes/species.cpp @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright (c) 2025 Team Dissolve and contributors + +#include "nodes/species.h" +#include "nodes/constants.h" +#include "nodes/dissolve.h" +#include + +namespace UnitTest +{ +class SpeciesNodeTest : public ::testing::Test +{ + public: + SpeciesNodeTest() : dissolve_(coreData_), root_(dissolve_) {} + + protected: + // We need a CoreData and Dissolve definition to properly + // instantiate DissolveGraph at present. + CoreData coreData_; + Dissolve dissolve_; + DissolveGraph root_; +}; + +TEST_F(SpeciesNodeTest, Creation) +{ + auto s = dynamic_cast(root_.createNode("Species", "s")); + ASSERT_EQ(s->name(), "s"); + auto option = s->findOption("Definition"); + ASSERT_NE(option, nullptr); + option->set("Hello, World!"); + ASSERT_EQ(s->run(), NodeConstants::ProcessResult::Failed); +} + +}; // namespace UnitTest From c61e51e3d191f8bc6a5ce4d6360c7dd8347e6851 Mon Sep 17 00:00:00 2001 From: Adam Washington Date: Wed, 12 Nov 2025 13:06:16 +0000 Subject: [PATCH 02/31] Successfully parse a species --- src/nodes/species.cpp | 18 ++++++----------- tests/nodes/species.cpp | 45 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 49 insertions(+), 14 deletions(-) diff --git a/src/nodes/species.cpp b/src/nodes/species.cpp index fe1abf2d21..1f6ed6d3d6 100644 --- a/src/nodes/species.cpp +++ b/src/nodes/species.cpp @@ -1,17 +1,17 @@ // SPDX-License-Identifier: GPL-3.0-or-later // Copyright (c) 2025 Team Dissolve and contributors -#include -#include -#include #include "species.h" #include "classes/coreData.h" #include "nodes/constants.h" +#include +#include +#include SpeciesNode::SpeciesNode(Graph *parentGraph) : Node(parentGraph) { - addOption("Definition", "TOML that defines the species", definition_); - addPointerOutput("Species", "Created species", species_); + addOption("Definition", "TOML that defines the species", definition_); + addPointerOutput("Species", "Created species", species_); } std::string_view SpeciesNode::type() const { return "Species"; } @@ -20,16 +20,10 @@ std::string_view SpeciesNode::summary() const { return "Produce a species"; } NodeConstants::ProcessResult SpeciesNode::process() { - CoreData coreData; - try { + CoreData coreData; std::istringstream stream(definition_); SerialisedValue node = toml::parse(stream); species_.deserialise(node, coreData); atomTypes_ = coreData.atomTypes(); return NodeConstants::ProcessResult::Success; - } - catch(...) - { - return NodeConstants::ProcessResult::Failed; - } } diff --git a/tests/nodes/species.cpp b/tests/nodes/species.cpp index 8c734492f4..82210650d0 100644 --- a/tests/nodes/species.cpp +++ b/tests/nodes/species.cpp @@ -27,8 +27,49 @@ TEST_F(SpeciesNodeTest, Creation) ASSERT_EQ(s->name(), "s"); auto option = s->findOption("Definition"); ASSERT_NE(option, nullptr); - option->set("Hello, World!"); - ASSERT_EQ(s->run(), NodeConstants::ProcessResult::Failed); + option->set(R"( +name="Water" +[[atoms]] +index=1 +z="O" +r=[ 0.156743, -0.152502, 0.317676 ] +charge=-0.82 +[[atoms]] +index=2 +z="H" +r=[-0.257130, 0.637822, 0.198948] +charge=0.41 +[[atoms]] +index=3 +z="H" +r=[0.100387, -0.485320, -0.516624] +charge=0.41 +[[bonds]] +i=1 +j=2 +form="Harmonic" +parameters=[4431.53, 1.012] +[[bonds]] +i=1 +j=3 +form="Harmonic" +parameters=[4431.53, 1.012] +[[angles]] +i=2 +j=1 +k=3 +form="Harmonic" +parameters=[317.5656, 113.24] +)"); + ASSERT_EQ(s->run(), NodeConstants::ProcessResult::Success); + auto result = s->findOutput("Species")->get(); + + ASSERT_EQ(result->atoms().size(), 3); + ASSERT_EQ(result->atom(0).charge(), -0.82); + ASSERT_EQ(result->atom(1).r().x, -0.257130); + + ASSERT_EQ(result->bonds().size(), 2); + ASSERT_EQ(result->angles().size(), 1); } }; // namespace UnitTest From 3e7687a5b1b4625cd42359db39382f733516fdb1 Mon Sep 17 00:00:00 2001 From: Adam Washington Date: Wed, 12 Nov 2025 14:40:21 +0000 Subject: [PATCH 03/31] Move to passing Species directly to the Node --- src/nodes/parameter.h | 5 +++++ src/nodes/species.cpp | 15 ++++--------- src/nodes/species.h | 4 +--- tests/nodes/species.cpp | 47 ++++++++++------------------------------- 4 files changed, 21 insertions(+), 50 deletions(-) diff --git a/src/nodes/parameter.h b/src/nodes/parameter.h index 60a58190c5..d532fe24de 100644 --- a/src/nodes/parameter.h +++ b/src/nodes/parameter.h @@ -464,6 +464,11 @@ template class SerialisableParameter : public Parameter::data_ = {}; } + else if constexpr (serialisablePointer) + { + CoreData coreData; // Temporary patch until we fix up the deserialisation + Parameter::data_->deserialise(node.at("data"), coreData); + } else { Parameter::data_ = toml::find(node, "data"); diff --git a/src/nodes/species.cpp b/src/nodes/species.cpp index 1f6ed6d3d6..7ff128a532 100644 --- a/src/nodes/species.cpp +++ b/src/nodes/species.cpp @@ -10,20 +10,13 @@ SpeciesNode::SpeciesNode(Graph *parentGraph) : Node(parentGraph) { - addOption("Definition", "TOML that defines the species", definition_); - addPointerOutput("Species", "Created species", species_); + species_ = std::make_shared(); + addOption("Data", "The data for this species", species_); + addPointerOutput("Species", "Created species", *species_); } std::string_view SpeciesNode::type() const { return "Species"; } std::string_view SpeciesNode::summary() const { return "Produce a species"; } -NodeConstants::ProcessResult SpeciesNode::process() -{ - CoreData coreData; - std::istringstream stream(definition_); - SerialisedValue node = toml::parse(stream); - species_.deserialise(node, coreData); - atomTypes_ = coreData.atomTypes(); - return NodeConstants::ProcessResult::Success; -} +NodeConstants::ProcessResult SpeciesNode::process() { return NodeConstants::ProcessResult::Unchanged; } diff --git a/src/nodes/species.h b/src/nodes/species.h index cdba74d33f..d9b5edeb07 100644 --- a/src/nodes/species.h +++ b/src/nodes/species.h @@ -24,10 +24,8 @@ class SpeciesNode : public Node * Data */ private: - // TOML Definition - std::string definition_; // Species object - Species species_; + std::shared_ptr species_; // Atom Types owned by the node std::vector> atomTypes_; diff --git a/tests/nodes/species.cpp b/tests/nodes/species.cpp index 82210650d0..2471e42e1d 100644 --- a/tests/nodes/species.cpp +++ b/tests/nodes/species.cpp @@ -25,43 +25,18 @@ TEST_F(SpeciesNodeTest, Creation) { auto s = dynamic_cast(root_.createNode("Species", "s")); ASSERT_EQ(s->name(), "s"); - auto option = s->findOption("Definition"); + auto option = s->findOption("Data"); ASSERT_NE(option, nullptr); - option->set(R"( -name="Water" -[[atoms]] -index=1 -z="O" -r=[ 0.156743, -0.152502, 0.317676 ] -charge=-0.82 -[[atoms]] -index=2 -z="H" -r=[-0.257130, 0.637822, 0.198948] -charge=0.41 -[[atoms]] -index=3 -z="H" -r=[0.100387, -0.485320, -0.516624] -charge=0.41 -[[bonds]] -i=1 -j=2 -form="Harmonic" -parameters=[4431.53, 1.012] -[[bonds]] -i=1 -j=3 -form="Harmonic" -parameters=[4431.53, 1.012] -[[angles]] -i=2 -j=1 -k=3 -form="Harmonic" -parameters=[317.5656, 113.24] -)"); - ASSERT_EQ(s->run(), NodeConstants::ProcessResult::Success); + + auto species = option->get>(); + species->addAtom(Elements::O, {0.156743, -0.152502, 0.317676}, -0.82); + species->addAtom(Elements::H, {-0.257130, 0.637822, 0.198948}, 0.41); + species->addAtom(Elements::H, {0.100387, -0.485320, -0.516624}, 0.41); + species->addBond(0, 1); + species->addBond(0, 2); + species->addAngle(1, 0, 2); + + ASSERT_EQ(s->run(), NodeConstants::ProcessResult::Unchanged); auto result = s->findOutput("Species")->get(); ASSERT_EQ(result->atoms().size(), 3); From 384f64fcf5afd6fde4de8786cb552fad6bd49600 Mon Sep 17 00:00:00 2001 From: Adam Washington Date: Wed, 12 Nov 2025 16:11:57 +0000 Subject: [PATCH 04/31] Add species to GUI menu --- src/gui/models/nodeGraph/parameterModel.cpp | 6 ++++++ src/gui/qml/nodeGraph/GraphView.qml | 5 +++++ src/gui/qml/nodeGraph/ParameterDelegate.qml | 7 +++++++ 3 files changed, 18 insertions(+) diff --git a/src/gui/models/nodeGraph/parameterModel.cpp b/src/gui/models/nodeGraph/parameterModel.cpp index 7a6ac579d6..591b9925f7 100644 --- a/src/gui/models/nodeGraph/parameterModel.cpp +++ b/src/gui/models/nodeGraph/parameterModel.cpp @@ -46,6 +46,8 @@ QVariant ParameterModel::data(const QModelIndex &index, int role) const return QString::fromStdString(it->second->get()); if (EnumRegistry::hasEnumOption(it->second->storedDataType())) return QVariant::fromValue(it->second->getAsInt()); + if (it->second->storedDataType() == typeid(std::shared_ptr)) + return QVariant::fromValue(it->second->get>()); return QString::fromStdString("Unrepresentable"); case TYPE: if (it->second->storedDataType() == typeid(Number)) @@ -58,6 +60,8 @@ QVariant ParameterModel::data(const QModelIndex &index, int role) const return "string"; if (EnumRegistry::hasEnumOption(it->second->storedDataType())) return "enum"; + if (it->second->storedDataType() == typeid(std::shared_ptr)) + return "species"; return "unknown"; case MODEL: @@ -97,6 +101,8 @@ bool ParameterModel::setData(const QModelIndex &index, const QVariant &value, in } if (EnumRegistry::hasEnumOption(it->storedDataType())) it->setFromInt(value.toInt()); + if (it->storedDataType() == typeid(std::shared_ptr)) + it->set>(qvariant_cast>(value)); return true; } diff --git a/src/gui/qml/nodeGraph/GraphView.qml b/src/gui/qml/nodeGraph/GraphView.qml index 31f5cda27a..f5f1303eca 100644 --- a/src/gui/qml/nodeGraph/GraphView.qml +++ b/src/gui/qml/nodeGraph/GraphView.qml @@ -114,6 +114,11 @@ Pane { onClicked: graphRoot.rootModel.emplace_back(Math.round(ctxMenuCatcher.mouseX), Math.round(ctxMenuCatcher.mouseY), "Graph", "New Graph") } + MenuItem { + text: "Species" + + onClicked: graphRoot.rootModel.emplace_back(Math.round(ctxMenuCatcher.mouseX), Math.round(ctxMenuCatcher.mouseY), "Species", "New Species") + } } } } diff --git a/src/gui/qml/nodeGraph/ParameterDelegate.qml b/src/gui/qml/nodeGraph/ParameterDelegate.qml index b91266fa60..9d9e5fe592 100644 --- a/src/gui/qml/nodeGraph/ParameterDelegate.qml +++ b/src/gui/qml/nodeGraph/ParameterDelegate.qml @@ -71,6 +71,13 @@ DelegateChooser { onTextChanged: param = text } } + DelegateChoice { + roleValue: "species" + + Button { + text: "It's a species" + } + } DelegateChoice { roleValue: "enum" From 14d5bde5a634cbf7347b4b3303e60dbd7053e191 Mon Sep 17 00:00:00 2001 From: Adam Washington Date: Fri, 14 Nov 2025 09:40:17 +0000 Subject: [PATCH 05/31] Eliminate keyword widgets --- src/gui/CMakeLists.txt | 16 +- src/gui/keywordWidgets/CMakeLists.txt | 120 ----------- src/gui/keywordWidgets/atomTypeVector.cpp | 72 ------- src/gui/keywordWidgets/atomTypeVector.h | 61 ------ src/gui/keywordWidgets/atomTypeVector.ui | 44 ---- src/gui/keywordWidgets/base.cpp | 6 - src/gui/keywordWidgets/base.h | 36 ---- src/gui/keywordWidgets/bool.cpp | 43 ---- src/gui/keywordWidgets/bool.h | 42 ---- src/gui/keywordWidgets/configuration.cpp | 75 ------- src/gui/keywordWidgets/configuration.h | 54 ----- src/gui/keywordWidgets/configuration.ui | 79 ------- .../keywordWidgets/configurationVector.cpp | 74 ------- src/gui/keywordWidgets/configurationVector.h | 59 ----- src/gui/keywordWidgets/configurationVector.ui | 44 ---- src/gui/keywordWidgets/dialog.cpp | 51 ----- src/gui/keywordWidgets/dialog.h | 47 ---- src/gui/keywordWidgets/dialog.ui | 101 --------- src/gui/keywordWidgets/double.cpp | 53 ----- src/gui/keywordWidgets/double.h | 42 ---- src/gui/keywordWidgets/dropDown.cpp | 59 ----- src/gui/keywordWidgets/dropDown.h | 51 ----- src/gui/keywordWidgets/dropDown.ui | 66 ------ src/gui/keywordWidgets/dropWidget.cpp | 14 -- src/gui/keywordWidgets/dropWidget.h | 28 --- src/gui/keywordWidgets/enumOptions.cpp | 63 ------ src/gui/keywordWidgets/enumOptions.h | 42 ---- .../expressionVariableVector.cpp | 43 ---- .../keywordWidgets/expressionVariableVector.h | 51 ----- .../expressionVariableVector.ui | 60 ------ src/gui/keywordWidgets/fileAndFormat.cpp | 165 -------------- src/gui/keywordWidgets/fileAndFormat.h | 62 ------ src/gui/keywordWidgets/fileAndFormat.ui | 138 ------------ src/gui/keywordWidgets/function1D.cpp | 153 ------------- src/gui/keywordWidgets/function1D.h | 60 ------ src/gui/keywordWidgets/function1D.ui | 204 ------------------ src/gui/keywordWidgets/integer.cpp | 52 ----- src/gui/keywordWidgets/integer.h | 42 ---- .../keywordWidgets/interactionPotential.cpp | 95 -------- src/gui/keywordWidgets/interactionPotential.h | 55 ----- .../keywordWidgets/interactionPotential.ui | 69 ------ src/gui/keywordWidgets/isotopologueSet.cpp | 148 ------------- src/gui/keywordWidgets/isotopologueSet.h | 60 ------ src/gui/keywordWidgets/isotopologueSet.ui | 166 -------------- src/gui/keywordWidgets/layer.cpp | 72 ------- src/gui/keywordWidgets/layer.h | 58 ----- src/gui/keywordWidgets/layer.ui | 68 ------ src/gui/keywordWidgets/module.cpp | 74 ------- src/gui/keywordWidgets/module.h | 56 ----- src/gui/keywordWidgets/module.ui | 79 ------- src/gui/keywordWidgets/moduleVector.cpp | 79 ------- src/gui/keywordWidgets/moduleVector.h | 61 ------ src/gui/keywordWidgets/moduleVector.ui | 44 ---- src/gui/keywordWidgets/node.cpp | 69 ------ src/gui/keywordWidgets/node.h | 52 ----- src/gui/keywordWidgets/node.ui | 79 ------- src/gui/keywordWidgets/nodeValue.cpp | 62 ------ src/gui/keywordWidgets/nodeValue.h | 52 ----- src/gui/keywordWidgets/nodeValue.ui | 72 ------- .../keywordWidgets/nodeValueEnumOptions.cpp | 92 -------- src/gui/keywordWidgets/nodeValueEnumOptions.h | 51 ----- .../keywordWidgets/nodeValueEnumOptions.ui | 75 ------- src/gui/keywordWidgets/nodeVector.cpp | 73 ------- src/gui/keywordWidgets/nodeVector.h | 58 ----- src/gui/keywordWidgets/nodeVector.ui | 52 ----- src/gui/keywordWidgets/optionalDouble.cpp | 68 ------ src/gui/keywordWidgets/optionalDouble.h | 44 ---- src/gui/keywordWidgets/optionalInt.cpp | 68 ------ src/gui/keywordWidgets/optionalInt.h | 44 ---- src/gui/keywordWidgets/producers.cpp | 119 ---------- src/gui/keywordWidgets/producers.h | 81 ------- src/gui/keywordWidgets/range.cpp | 93 -------- src/gui/keywordWidgets/range.h | 47 ---- src/gui/keywordWidgets/range.ui | 88 -------- src/gui/keywordWidgets/rangeVector.cpp | 78 ------- src/gui/keywordWidgets/rangeVector.h | 59 ----- src/gui/keywordWidgets/rangeVector.ui | 83 ------- src/gui/keywordWidgets/species.cpp | 72 ------- src/gui/keywordWidgets/species.h | 54 ----- src/gui/keywordWidgets/species.ui | 79 ------- src/gui/keywordWidgets/speciesSite.cpp | 142 ------------ src/gui/keywordWidgets/speciesSite.h | 70 ------ src/gui/keywordWidgets/speciesSite.ui | 172 --------------- src/gui/keywordWidgets/speciesSiteVector.cpp | 77 ------- src/gui/keywordWidgets/speciesSiteVector.h | 63 ------ src/gui/keywordWidgets/speciesSiteVector.ui | 52 ----- src/gui/keywordWidgets/speciesVector.cpp | 72 ------- src/gui/keywordWidgets/speciesVector.h | 59 ----- src/gui/keywordWidgets/speciesVector.ui | 44 ---- src/gui/keywordWidgets/stdString.cpp | 42 ---- src/gui/keywordWidgets/stdString.h | 42 ---- src/gui/keywordWidgets/vec3Double.cpp | 108 ---------- src/gui/keywordWidgets/vec3Double.h | 48 ----- src/gui/keywordWidgets/vec3Double.ui | 105 --------- src/gui/keywordWidgets/vec3Integer.cpp | 101 --------- src/gui/keywordWidgets/vec3Integer.h | 49 ----- src/gui/keywordWidgets/vec3Integer.ui | 77 ------- src/gui/keywordWidgets/vec3Labels.cpp | 67 ------ src/gui/keywordWidgets/vec3Labels.h | 15 -- src/gui/keywordWidgets/vec3NodeValue.cpp | 119 ---------- src/gui/keywordWidgets/vec3NodeValue.h | 52 ----- src/gui/keywordWidgets/vec3NodeValue.ui | 155 ------------- .../keywordWidgets/weightedModuleVector.cpp | 84 -------- src/gui/keywordWidgets/weightedModuleVector.h | 61 ------ .../keywordWidgets/weightedModuleVector.ui | 44 ---- src/gui/keywordWidgets/widget.cpp | 137 ------------ src/gui/keywordWidgets/widget.h | 52 ----- src/gui/keywordWidgets/widgetGroupHeader.cpp | 16 -- src/gui/keywordWidgets/widgetGroupHeader.h | 23 -- src/gui/keywordWidgets/widgetGroupHeader.ui | 115 ---------- tests/CMakeLists.txt | 2 +- tests/gui/CMakeLists.txt | 2 - 112 files changed, 2 insertions(+), 7785 deletions(-) delete mode 100755 src/gui/keywordWidgets/CMakeLists.txt delete mode 100644 src/gui/keywordWidgets/atomTypeVector.cpp delete mode 100644 src/gui/keywordWidgets/atomTypeVector.h delete mode 100644 src/gui/keywordWidgets/atomTypeVector.ui delete mode 100644 src/gui/keywordWidgets/base.cpp delete mode 100644 src/gui/keywordWidgets/base.h delete mode 100644 src/gui/keywordWidgets/bool.cpp delete mode 100644 src/gui/keywordWidgets/bool.h delete mode 100644 src/gui/keywordWidgets/configuration.cpp delete mode 100644 src/gui/keywordWidgets/configuration.h delete mode 100644 src/gui/keywordWidgets/configuration.ui delete mode 100644 src/gui/keywordWidgets/configurationVector.cpp delete mode 100644 src/gui/keywordWidgets/configurationVector.h delete mode 100644 src/gui/keywordWidgets/configurationVector.ui delete mode 100644 src/gui/keywordWidgets/dialog.cpp delete mode 100644 src/gui/keywordWidgets/dialog.h delete mode 100644 src/gui/keywordWidgets/dialog.ui delete mode 100644 src/gui/keywordWidgets/double.cpp delete mode 100644 src/gui/keywordWidgets/double.h delete mode 100644 src/gui/keywordWidgets/dropDown.cpp delete mode 100644 src/gui/keywordWidgets/dropDown.h delete mode 100644 src/gui/keywordWidgets/dropDown.ui delete mode 100644 src/gui/keywordWidgets/dropWidget.cpp delete mode 100644 src/gui/keywordWidgets/dropWidget.h delete mode 100644 src/gui/keywordWidgets/enumOptions.cpp delete mode 100644 src/gui/keywordWidgets/enumOptions.h delete mode 100644 src/gui/keywordWidgets/expressionVariableVector.cpp delete mode 100644 src/gui/keywordWidgets/expressionVariableVector.h delete mode 100644 src/gui/keywordWidgets/expressionVariableVector.ui delete mode 100644 src/gui/keywordWidgets/fileAndFormat.cpp delete mode 100644 src/gui/keywordWidgets/fileAndFormat.h delete mode 100644 src/gui/keywordWidgets/fileAndFormat.ui delete mode 100644 src/gui/keywordWidgets/function1D.cpp delete mode 100644 src/gui/keywordWidgets/function1D.h delete mode 100644 src/gui/keywordWidgets/function1D.ui delete mode 100644 src/gui/keywordWidgets/integer.cpp delete mode 100644 src/gui/keywordWidgets/integer.h delete mode 100644 src/gui/keywordWidgets/interactionPotential.cpp delete mode 100644 src/gui/keywordWidgets/interactionPotential.h delete mode 100644 src/gui/keywordWidgets/interactionPotential.ui delete mode 100644 src/gui/keywordWidgets/isotopologueSet.cpp delete mode 100644 src/gui/keywordWidgets/isotopologueSet.h delete mode 100644 src/gui/keywordWidgets/isotopologueSet.ui delete mode 100644 src/gui/keywordWidgets/layer.cpp delete mode 100644 src/gui/keywordWidgets/layer.h delete mode 100644 src/gui/keywordWidgets/layer.ui delete mode 100644 src/gui/keywordWidgets/module.cpp delete mode 100644 src/gui/keywordWidgets/module.h delete mode 100644 src/gui/keywordWidgets/module.ui delete mode 100644 src/gui/keywordWidgets/moduleVector.cpp delete mode 100644 src/gui/keywordWidgets/moduleVector.h delete mode 100644 src/gui/keywordWidgets/moduleVector.ui delete mode 100644 src/gui/keywordWidgets/node.cpp delete mode 100644 src/gui/keywordWidgets/node.h delete mode 100644 src/gui/keywordWidgets/node.ui delete mode 100644 src/gui/keywordWidgets/nodeValue.cpp delete mode 100644 src/gui/keywordWidgets/nodeValue.h delete mode 100644 src/gui/keywordWidgets/nodeValue.ui delete mode 100644 src/gui/keywordWidgets/nodeValueEnumOptions.cpp delete mode 100644 src/gui/keywordWidgets/nodeValueEnumOptions.h delete mode 100644 src/gui/keywordWidgets/nodeValueEnumOptions.ui delete mode 100644 src/gui/keywordWidgets/nodeVector.cpp delete mode 100644 src/gui/keywordWidgets/nodeVector.h delete mode 100644 src/gui/keywordWidgets/nodeVector.ui delete mode 100644 src/gui/keywordWidgets/optionalDouble.cpp delete mode 100644 src/gui/keywordWidgets/optionalDouble.h delete mode 100644 src/gui/keywordWidgets/optionalInt.cpp delete mode 100644 src/gui/keywordWidgets/optionalInt.h delete mode 100644 src/gui/keywordWidgets/producers.cpp delete mode 100644 src/gui/keywordWidgets/producers.h delete mode 100644 src/gui/keywordWidgets/range.cpp delete mode 100644 src/gui/keywordWidgets/range.h delete mode 100644 src/gui/keywordWidgets/range.ui delete mode 100644 src/gui/keywordWidgets/rangeVector.cpp delete mode 100644 src/gui/keywordWidgets/rangeVector.h delete mode 100644 src/gui/keywordWidgets/rangeVector.ui delete mode 100644 src/gui/keywordWidgets/species.cpp delete mode 100644 src/gui/keywordWidgets/species.h delete mode 100644 src/gui/keywordWidgets/species.ui delete mode 100644 src/gui/keywordWidgets/speciesSite.cpp delete mode 100644 src/gui/keywordWidgets/speciesSite.h delete mode 100644 src/gui/keywordWidgets/speciesSite.ui delete mode 100644 src/gui/keywordWidgets/speciesSiteVector.cpp delete mode 100644 src/gui/keywordWidgets/speciesSiteVector.h delete mode 100644 src/gui/keywordWidgets/speciesSiteVector.ui delete mode 100644 src/gui/keywordWidgets/speciesVector.cpp delete mode 100644 src/gui/keywordWidgets/speciesVector.h delete mode 100644 src/gui/keywordWidgets/speciesVector.ui delete mode 100644 src/gui/keywordWidgets/stdString.cpp delete mode 100644 src/gui/keywordWidgets/stdString.h delete mode 100644 src/gui/keywordWidgets/vec3Double.cpp delete mode 100644 src/gui/keywordWidgets/vec3Double.h delete mode 100644 src/gui/keywordWidgets/vec3Double.ui delete mode 100644 src/gui/keywordWidgets/vec3Integer.cpp delete mode 100644 src/gui/keywordWidgets/vec3Integer.h delete mode 100644 src/gui/keywordWidgets/vec3Integer.ui delete mode 100644 src/gui/keywordWidgets/vec3Labels.cpp delete mode 100644 src/gui/keywordWidgets/vec3Labels.h delete mode 100644 src/gui/keywordWidgets/vec3NodeValue.cpp delete mode 100644 src/gui/keywordWidgets/vec3NodeValue.h delete mode 100644 src/gui/keywordWidgets/vec3NodeValue.ui delete mode 100644 src/gui/keywordWidgets/weightedModuleVector.cpp delete mode 100644 src/gui/keywordWidgets/weightedModuleVector.h delete mode 100644 src/gui/keywordWidgets/weightedModuleVector.ui delete mode 100644 src/gui/keywordWidgets/widget.cpp delete mode 100644 src/gui/keywordWidgets/widget.h delete mode 100644 src/gui/keywordWidgets/widgetGroupHeader.cpp delete mode 100644 src/gui/keywordWidgets/widgetGroupHeader.h delete mode 100644 src/gui/keywordWidgets/widgetGroupHeader.ui diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index 3eec0722a9..5279a15329 100755 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -52,15 +52,6 @@ add_library( viewer_view.cpp viewer.h # Widgets and Wizards - moduleControlWidget.cpp - moduleControlWidget.h - moduleControlWidget.ui - nodeControlWidget.cpp - nodeControlWidget.h - nodeControlWidget.ui - generatorWidget.cpp - generatorWidget.h - generatorWidget.ui selectAtomTypeWidget.cpp selectAtomTypeWidget.h selectAtomTypeWidget.ui @@ -132,9 +123,6 @@ add_library( speciesCellDialog.h speciesCellDialog.ui # Main Tabs - configurationTab.cpp - configurationTab.h - configurationTab.ui forcefieldTab.cpp forcefieldTab.h forcefieldTab.ui @@ -190,8 +178,7 @@ target_include_directories( target_link_libraries( gui - PRIVATE keywordWidgets - delegates + PRIVATE delegates widgets models base @@ -207,7 +194,6 @@ target_link_libraries( ) # Subdirectories -add_subdirectory(keywordWidgets) add_subdirectory(delegates) add_subdirectory(render) add_subdirectory(widgets) diff --git a/src/gui/keywordWidgets/CMakeLists.txt b/src/gui/keywordWidgets/CMakeLists.txt deleted file mode 100755 index b8199d7205..0000000000 --- a/src/gui/keywordWidgets/CMakeLists.txt +++ /dev/null @@ -1,120 +0,0 @@ -# Target 'keywordWidgets' -add_library( - keywordWidgets - atomTypeVector.cpp - atomTypeVector.h - atomTypeVector.ui - base.cpp - base.h - bool.cpp - bool.h - CMakeLists.txt - configuration.cpp - configuration.h - configuration.ui - configurationVector.cpp - configurationVector.h - configurationVector.ui - dialog.cpp - dialog.h - dialog.ui - double.cpp - double.h - dropDown.cpp - dropDown.h - dropDown.ui - dropWidget.cpp - dropWidget.h - enumOptions.cpp - enumOptions.h - expressionVariableVector.cpp - expressionVariableVector.h - expressionVariableVector.ui - fileAndFormat.cpp - fileAndFormat.h - fileAndFormat.ui - function1D.cpp - function1D.h - function1D.ui - integer.cpp - integer.h - interactionPotential.cpp - interactionPotential.h - interactionPotential.ui - isotopologueSet.cpp - isotopologueSet.h - isotopologueSet.ui - layer.cpp - layer.h - layer.ui - module.cpp - module.h - module.ui - moduleVector.cpp - moduleVector.h - moduleVector.ui - node.cpp - node.h - node.ui - nodeValue.cpp - nodeValueEnumOptions.cpp - nodeValueEnumOptions.h - nodeValueEnumOptions.ui - nodeValue.h - nodeValue.ui - nodeVector.cpp - nodeVector.h - nodeVector.ui - optionalDouble.cpp - optionalDouble.h - optionalInt.cpp - optionalInt.h - producers.cpp - producers.h - range.cpp - range.h - range.ui - rangeVector.cpp - rangeVector.h - rangeVector.ui - species.cpp - species.h - speciesSite.cpp - speciesSite.h - speciesSite.ui - speciesSiteVector.cpp - speciesSiteVector.h - speciesSiteVector.ui - species.ui - speciesVector.cpp - speciesVector.h - speciesVector.ui - stdString.cpp - stdString.h - vec3Double.cpp - vec3Double.h - vec3Double.ui - vec3Integer.cpp - vec3Integer.h - vec3Integer.ui - vec3Labels.cpp - vec3Labels.h - vec3NodeValue.cpp - vec3NodeValue.h - vec3NodeValue.ui - weightedModuleVector.cpp - weightedModuleVector.h - weightedModuleVector.ui - widget.cpp - widgetGroupHeader.cpp - widgetGroupHeader.h - widgetGroupHeader.ui - widget.h -) -target_include_directories(keywordWidgets PRIVATE ${PROJECT_SOURCE_DIR}/src ${PROJECT_BINARY_DIR}/src ${Qt6Widgets_INCLUDE_DIRS}) -target_link_libraries(keywordWidgets PRIVATE base) - -# Because Qt has its own way of checking for C++17 -if(MSVC) - target_compile_options(keywordWidgets PUBLIC /Zc:__cplusplus) -endif(MSVC) diff --git a/src/gui/keywordWidgets/atomTypeVector.cpp b/src/gui/keywordWidgets/atomTypeVector.cpp deleted file mode 100644 index ea0e2d4a89..0000000000 --- a/src/gui/keywordWidgets/atomTypeVector.cpp +++ /dev/null @@ -1,72 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#include "gui/keywordWidgets/atomTypeVector.h" -#include "classes/atomType.h" -#include "classes/coreData.h" -#include "gui/keywordWidgets/dropDown.h" -#include "templates/algorithms.h" -#include -#include -#include - -AtomTypeVectorKeywordWidget::AtomTypeVectorKeywordWidget(QWidget *parent, AtomTypeVectorKeyword *keyword, - const CoreData &coreData) - : KeywordDropDown(this), KeywordWidgetBase(coreData), keyword_(keyword), atomTypeModel_(coreData) -{ - // Create and set up the UI for our widget in the drop-down's widget container - ui_.setupUi(dropWidget()); - - // Set up the model - ui_.AtomTypeList->setModel(&atomTypeModel_); - atomTypeModel_.setCheckStateData(keyword_->data()); - resetModelData(); - - // Connect signals / slots - connect(&atomTypeModel_, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), this, - SLOT(modelDataChanged(const QModelIndex &, const QModelIndex &))); -} - -/* - * Widgets - */ - -void AtomTypeVectorKeywordWidget::modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight) -{ - if (refreshing_) - return; - - updateSummaryText(); - - Q_EMIT(keywordDataChanged(keyword_->editSignals())); -} - -/* - * Update - */ - -// Reset model data -void AtomTypeVectorKeywordWidget::resetModelData() -{ - refreshing_ = true; - - atomTypeModel_.setData(coreData_.atomTypes()); - atomTypeModel_.setCheckStateData(keyword_->data()); - - updateSummaryText(); - - refreshing_ = false; -} - -// Update value displayed in widget -void AtomTypeVectorKeywordWidget::updateValue(const Flags &mutationFlags) { resetModelData(); } - -// Update summary text -void AtomTypeVectorKeywordWidget::updateSummaryText() -{ - if (keyword_->data().empty()) - setSummaryText(""); - else - setSummaryText( - QString::fromStdString(joinStrings(keyword_->data(), ", ", [](const auto &at) { return at.get()->name(); }))); -} diff --git a/src/gui/keywordWidgets/atomTypeVector.h b/src/gui/keywordWidgets/atomTypeVector.h deleted file mode 100644 index f29fb5d547..0000000000 --- a/src/gui/keywordWidgets/atomTypeVector.h +++ /dev/null @@ -1,61 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#pragma once - -#include "gui/keywordWidgets/base.h" -#include "gui/keywordWidgets/dropDown.h" -#include "gui/keywordWidgets/ui_atomTypeVector.h" -#include "gui/models/atomTypeModel.h" -#include "keywords/atomTypeVector.h" -#include -#include -#include - -// Forward Declarations -class AtomType; - -class AtomTypeVectorKeywordWidget : public KeywordDropDown, public KeywordWidgetBase -{ - // All Qt declarations must include this macro - Q_OBJECT - - public: - AtomTypeVectorKeywordWidget(QWidget *parent, AtomTypeVectorKeyword *keyword, const CoreData &coreData); - - /* - * Keyword - */ - private: - // Associated keyword - AtomTypeVectorKeyword *keyword_; - - /* - * Widgets - */ - private: - // Main form declaration - Ui::AtomTypeVectorWidget ui_; - // AtomType model - AtomTypeModel atomTypeModel_; - - private Q_SLOTS: - void modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight); - - Q_SIGNALS: - // Keyword data changed - void keywordDataChanged(int flags); - - /* - * Update - */ - private: - // Reset model data - void resetModelData(); - - public: - // Update value displayed in widget - void updateValue(const Flags &mutationFlags) override; - // Update summary text - void updateSummaryText(); -}; diff --git a/src/gui/keywordWidgets/atomTypeVector.ui b/src/gui/keywordWidgets/atomTypeVector.ui deleted file mode 100644 index 79a804aa31..0000000000 --- a/src/gui/keywordWidgets/atomTypeVector.ui +++ /dev/null @@ -1,44 +0,0 @@ - - - AtomTypeVectorWidget - - - - 0 - 0 - 144 - 218 - - - - - 10 - - - - Form - - - - 0 - - - 0 - - - 0 - - - 0 - - - 4 - - - - - - - - - diff --git a/src/gui/keywordWidgets/base.cpp b/src/gui/keywordWidgets/base.cpp deleted file mode 100644 index e266dbba20..0000000000 --- a/src/gui/keywordWidgets/base.cpp +++ /dev/null @@ -1,6 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#include "gui/keywordWidgets/base.h" - -KeywordWidgetBase::KeywordWidgetBase(const CoreData &coreData) : coreData_(coreData), refreshing_(false) {} diff --git a/src/gui/keywordWidgets/base.h b/src/gui/keywordWidgets/base.h deleted file mode 100644 index f000fc0171..0000000000 --- a/src/gui/keywordWidgets/base.h +++ /dev/null @@ -1,36 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#pragma once - -#include "gui/signals.h" -#include "templates/flags.h" - -// Forward Declarations -class CoreData; -class GenericList; - -// Keyword Widget Base Class -class KeywordWidgetBase -{ - public: - KeywordWidgetBase(const CoreData &coreData); - - /* - * CoreData Reference - */ - protected: - // CoreData source - const CoreData &coreData_; - - /* - * Update - */ - protected: - // Whether the widget is currently refreshing - bool refreshing_; - - public: - // Update value displayed in widget - virtual void updateValue(const Flags &mutationFlags = {}) = 0; -}; diff --git a/src/gui/keywordWidgets/bool.cpp b/src/gui/keywordWidgets/bool.cpp deleted file mode 100644 index 3c8f8b152f..0000000000 --- a/src/gui/keywordWidgets/bool.cpp +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#include "gui/keywordWidgets/bool.h" - -BoolKeywordWidget::BoolKeywordWidget(QWidget *parent, BoolKeyword *keyword, const CoreData &coreData) - : QCheckBox(parent), KeywordWidgetBase(coreData), keyword_(keyword) -{ - // Set current state - setChecked(keyword_->data()); - - // Connect the - connect(this, SIGNAL(clicked(bool)), this, SLOT(checkBoxClicked(bool))); -} - -/* - * Signals / Slots - */ - -// Check box state changed -void BoolKeywordWidget::checkBoxClicked(bool checked) -{ - if (refreshing_) - return; - - keyword_->setData(checked); - - Q_EMIT(keywordDataChanged(keyword_->editSignals())); -} - -/* - * Update - */ - -// Update value displayed in widget -void BoolKeywordWidget::updateValue(const Flags &mutationFlags) -{ - refreshing_ = true; - - setChecked(keyword_->data()); - - refreshing_ = false; -} diff --git a/src/gui/keywordWidgets/bool.h b/src/gui/keywordWidgets/bool.h deleted file mode 100644 index fa7cec65f8..0000000000 --- a/src/gui/keywordWidgets/bool.h +++ /dev/null @@ -1,42 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#pragma once - -#include "gui/keywordWidgets/base.h" -#include "keywords/bool.h" -#include - -class BoolKeywordWidget : public QCheckBox, public KeywordWidgetBase -{ - // All Qt declarations must include this macro - Q_OBJECT - - public: - BoolKeywordWidget(QWidget *parent, BoolKeyword *keyword, const CoreData &coreData); - - /* - * Keyword - */ - private: - // Associated keyword - BoolKeyword *keyword_; - - /* - * Signals / Slots - */ - private Q_SLOTS: - // Check box state changed - void checkBoxClicked(bool checked); - - Q_SIGNALS: - // Keyword data changed - void keywordDataChanged(int flags); - - /* - * Update - */ - public: - // Update value displayed in widget - void updateValue(const Flags &mutationFlags) override; -}; diff --git a/src/gui/keywordWidgets/configuration.cpp b/src/gui/keywordWidgets/configuration.cpp deleted file mode 100644 index a0b8d5693f..0000000000 --- a/src/gui/keywordWidgets/configuration.cpp +++ /dev/null @@ -1,75 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#include "gui/keywordWidgets/configuration.h" -#include "classes/coreData.h" -#include "gui/helpers/mouseWheelAdjustmentGuard.h" - -ConfigurationKeywordWidget::ConfigurationKeywordWidget(QWidget *parent, ConfigurationKeyword *keyword, const CoreData &coreData) - : QWidget(parent), KeywordWidgetBase(coreData), keyword_(keyword) -{ - // Setup our UI - ui_.setupUi(this); - - refreshing_ = false; - - ui_.ConfigurationCombo->setModel(&configurationModel_); - resetModelData(); - - // Set event filtering so that we do not blindly accept mouse wheel events (problematic since we will exist in a - // QScrollArea) - ui_.ConfigurationCombo->installEventFilter(new MouseWheelWidgetAdjustmentGuard(ui_.ConfigurationCombo)); -} - -/* - * Widgets - */ - -void ConfigurationKeywordWidget::on_ConfigurationCombo_currentIndexChanged(int index) -{ - if (refreshing_) - return; - - // Get data from the selected item - if (index == -1) - keyword_->data() = nullptr; - else - keyword_->data() = ui_.ConfigurationCombo->currentData(Qt::UserRole).value(); - - Q_EMIT(keywordDataChanged(keyword_->editSignals())); -} - -void ConfigurationKeywordWidget::on_ClearButton_clicked(bool checked) -{ - if (ui_.ConfigurationCombo->currentIndex() == -1 && !keyword_->data()) - return; - - ui_.ConfigurationCombo->setCurrentIndex(-1); -} - -/* - * Update - */ - -// Reset model data -void ConfigurationKeywordWidget::resetModelData() -{ - refreshing_ = true; - - configurationModel_.setData(coreData_.configurations()); - - // Set current index based on keyword data - auto it = std::find_if(coreData_.configurations().begin(), coreData_.configurations().end(), - [&](const auto &cfg) { return cfg.get() == keyword_->data(); }); - ui_.ConfigurationCombo->setCurrentIndex(it == coreData_.configurations().end() ? -1 - : it - coreData_.configurations().begin()); - - refreshing_ = false; -} - -// Update value displayed in widget -void ConfigurationKeywordWidget::updateValue(const Flags &mutationFlags) -{ - if (mutationFlags.isSet(DissolveSignals::ConfigurationsMutated)) - resetModelData(); -} diff --git a/src/gui/keywordWidgets/configuration.h b/src/gui/keywordWidgets/configuration.h deleted file mode 100644 index d3226fdf84..0000000000 --- a/src/gui/keywordWidgets/configuration.h +++ /dev/null @@ -1,54 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#pragma once - -#include "gui/keywordWidgets/base.h" -#include "gui/keywordWidgets/ui_configuration.h" -#include "gui/models/configurationModel.h" -#include "keywords/configuration.h" -#include - -class ConfigurationKeywordWidget : public QWidget, public KeywordWidgetBase -{ - // All Qt declarations must include this macro - Q_OBJECT - - public: - ConfigurationKeywordWidget(QWidget *parent, ConfigurationKeyword *keyword, const CoreData &coreData); - - /* - * Keyword - */ - private: - // Associated keyword - ConfigurationKeyword *keyword_; - - /* - * Widgets - */ - private: - // Main form declaration - Ui::ConfigurationWidget ui_; - // Model for combo box - ConfigurationModel configurationModel_; - - private Q_SLOTS: - void on_ConfigurationCombo_currentIndexChanged(int index); - void on_ClearButton_clicked(bool checked); - - Q_SIGNALS: - // Keyword data changed - void keywordDataChanged(int flags); - - /* - * Update - */ - private: - // Reset model data - void resetModelData(); - - public: - // Update value displayed in widget - void updateValue(const Flags &mutationFlags) override; -}; diff --git a/src/gui/keywordWidgets/configuration.ui b/src/gui/keywordWidgets/configuration.ui deleted file mode 100644 index 0547f39b4c..0000000000 --- a/src/gui/keywordWidgets/configuration.ui +++ /dev/null @@ -1,79 +0,0 @@ - - - ConfigurationWidget - - - - 0 - 0 - 207 - 29 - - - - - 0 - 0 - - - - - 10 - - - - Form - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - - - - - Clear selected - - - ... - - - - :/general/icons/clear.svg:/general/icons/clear.svg - - - - 16 - 16 - - - - - - - - - - - diff --git a/src/gui/keywordWidgets/configurationVector.cpp b/src/gui/keywordWidgets/configurationVector.cpp deleted file mode 100644 index 476e64d67c..0000000000 --- a/src/gui/keywordWidgets/configurationVector.cpp +++ /dev/null @@ -1,74 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#include "gui/keywordWidgets/configurationVector.h" -#include "classes/configuration.h" -#include "classes/coreData.h" -#include "module/module.h" -#include "templates/algorithms.h" -#include -#include -#include - -ConfigurationVectorKeywordWidget::ConfigurationVectorKeywordWidget(QWidget *parent, ConfigurationVectorKeyword *keyword, - const CoreData &coreData) - : KeywordDropDown(this), KeywordWidgetBase(coreData), keyword_(keyword) -{ - // Create and set up the UI for our widget in the drop-down's widget container - ui_.setupUi(dropWidget()); - - // Set up the model - ui_.ConfigurationList->setModel(&configurationModel_); - configurationModel_.setCheckStateData(keyword_->data()); - resetModelData(); - - // Connect signals / slots - connect(&configurationModel_, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), this, - SLOT(modelDataChanged(const QModelIndex &, const QModelIndex &))); -} - -/* - * Widgets - */ - -void ConfigurationVectorKeywordWidget::modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight) -{ - if (refreshing_) - return; - - updateSummaryText(); - - Q_EMIT(keywordDataChanged(keyword_->editSignals())); -} - -/* - * Update - */ - -// Reset model data -void ConfigurationVectorKeywordWidget::resetModelData() -{ - refreshing_ = true; - - configurationModel_.setData(coreData_.configurations()); - - updateSummaryText(); - - refreshing_ = false; -} - -// Update value displayed in widget -void ConfigurationVectorKeywordWidget::updateValue(const Flags &mutationFlags) -{ - resetModelData(); -} - -// Update summary text -void ConfigurationVectorKeywordWidget::updateSummaryText() -{ - if (keyword_->data().empty()) - setSummaryText(""); - else - setSummaryText( - QString::fromStdString(joinStrings(keyword_->data(), ", ", [](const auto &cfg) { return cfg->name(); }))); -} diff --git a/src/gui/keywordWidgets/configurationVector.h b/src/gui/keywordWidgets/configurationVector.h deleted file mode 100644 index 4ecc43624b..0000000000 --- a/src/gui/keywordWidgets/configurationVector.h +++ /dev/null @@ -1,59 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#pragma once - -#include "gui/keywordWidgets/base.h" -#include "gui/keywordWidgets/dropDown.h" -#include "gui/keywordWidgets/ui_configurationVector.h" -#include "gui/models/configurationModel.h" -#include "keywords/configurationVector.h" -#include - -// Forward Declarations -class Configuration; - -class ConfigurationVectorKeywordWidget : public KeywordDropDown, public KeywordWidgetBase -{ - // All Qt declarations must include this macro - Q_OBJECT - - public: - ConfigurationVectorKeywordWidget(QWidget *parent, ConfigurationVectorKeyword *keyword, const CoreData &coreData); - - /* - * Keyword - */ - private: - // Associated keyword - ConfigurationVectorKeyword *keyword_; - - /* - * Widgets - */ - private: - // Main form declaration - Ui::ConfigurationVectorWidget ui_; - // Model for Configuration - ConfigurationModel configurationModel_; - - private Q_SLOTS: - void modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight); - - Q_SIGNALS: - // Keyword data changed - void keywordDataChanged(int flags); - - /* - * Update - */ - private: - // Reset model data - void resetModelData(); - - public: - // Update value displayed in widget - void updateValue(const Flags &mutationFlags) override; - // Update summary text - void updateSummaryText(); -}; diff --git a/src/gui/keywordWidgets/configurationVector.ui b/src/gui/keywordWidgets/configurationVector.ui deleted file mode 100644 index c65b112f1d..0000000000 --- a/src/gui/keywordWidgets/configurationVector.ui +++ /dev/null @@ -1,44 +0,0 @@ - - - ConfigurationVectorWidget - - - - 0 - 0 - 144 - 218 - - - - - 10 - - - - Form - - - - 0 - - - 0 - - - 0 - - - 0 - - - 4 - - - - - - - - - diff --git a/src/gui/keywordWidgets/dialog.cpp b/src/gui/keywordWidgets/dialog.cpp deleted file mode 100644 index 61f6768ce3..0000000000 --- a/src/gui/keywordWidgets/dialog.cpp +++ /dev/null @@ -1,51 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#include "gui/keywordWidgets/dialog.h" -#include "classes/coreData.h" -#include "classes/species.h" -#include "keywords/organiser.h" - -KeywordsDialog::KeywordsDialog(QWidget *parent, const KeywordStore &keywordStore, CoreData &coreData) : coreData_(coreData) -{ - ui_.setupUi(this); - - if (keywordStore.nVisibleKeywords() == 0) - return; - - // We can only display a single section of widgets at present - if (keywordStore.sections().size() != 1) - Messenger::warn("There are {} keyword sections defined, but only one can be displayed. Tell the developer!\n", - keywordStore.sections().size()); - - ui_.Keywords->setUp(keywordStore.sections().front(), coreData); - - connect(ui_.Keywords, SIGNAL(keywordChanged(int)), this, SLOT(keywordChanged(int))); -} - -// Run the dialog -void KeywordsDialog::showOptions() -{ - keywordsModified_ = false; - keywordSignalMask_ = 0; - - exec(); -} - -// Return whether any keywords have been modified in the current 'show' -bool KeywordsDialog::keywordsModified() const { return keywordsModified_; } - -// Return combined signal mask for all keyword changes -Flags KeywordsDialog::keywordSignalMask() const { return keywordSignalMask_; } - -/* - * Slots - */ - -void KeywordsDialog::keywordChanged(int signalMask) -{ - keywordsModified_ = true; - keywordSignalMask_ += signalMask; -} - -void KeywordsDialog::on_OKButton_clicked(bool checked) { accept(); } diff --git a/src/gui/keywordWidgets/dialog.h b/src/gui/keywordWidgets/dialog.h deleted file mode 100644 index 943e4feaab..0000000000 --- a/src/gui/keywordWidgets/dialog.h +++ /dev/null @@ -1,47 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#pragma once - -#include "gui/keywordWidgets/ui_dialog.h" -#include "keywords/base.h" -#include - -// Forward Declarations -class CoreData; -class KeywordStoreOrganiser; - -// Keywords Dialog -class KeywordsDialog : public QDialog -{ - Q_OBJECT - - public: - KeywordsDialog(QWidget *parent, const KeywordStore &keywordStore, CoreData &coreData); - ~KeywordsDialog() = default; - - private: - // Main form declaration - Ui::KeywordsDialog ui_; - // CoreData reference - CoreData &coreData_; - // Whether any keywords have been modified in the current 'show' - bool keywordsModified_{false}; - // Combined signal mask for all keyword changes - Flags keywordSignalMask_; - - public: - // Run the dialog - void showOptions(); - // Return whether any keywords have been modified in the current 'show' - bool keywordsModified() const; - // Return combined signal mask for all keyword changes - Flags keywordSignalMask() const; - - /* - * Slots - */ - private Q_SLOTS: - void keywordChanged(int signalMask); - void on_OKButton_clicked(bool checked); -}; diff --git a/src/gui/keywordWidgets/dialog.ui b/src/gui/keywordWidgets/dialog.ui deleted file mode 100644 index c11d4b1dc2..0000000000 --- a/src/gui/keywordWidgets/dialog.ui +++ /dev/null @@ -1,101 +0,0 @@ - - - KeywordsDialog - - - Qt::ApplicationModal - - - - 0 - 0 - 264 - 203 - - - - - 10 - - - - Available Keywords - - - - :/general/icons/species.svg:/general/icons/species.svg - - - - 4 - - - 4 - - - 4 - - - 4 - - - 4 - - - - - - 0 - 0 - - - - - - - - 4 - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - &OK - - - false - - - true - - - - - - - - - - KeywordsWidget - QWidget -
gui/keywordWidgets/widget.h
- 1 -
-
- - - - -
diff --git a/src/gui/keywordWidgets/double.cpp b/src/gui/keywordWidgets/double.cpp deleted file mode 100644 index 37d2134211..0000000000 --- a/src/gui/keywordWidgets/double.cpp +++ /dev/null @@ -1,53 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#include "gui/keywordWidgets/double.h" -#include "gui/helpers/mouseWheelAdjustmentGuard.h" - -DoubleKeywordWidget::DoubleKeywordWidget(QWidget *parent, DoubleKeyword *keyword, const CoreData &coreData) - : ExponentialSpin(parent), KeywordWidgetBase(coreData), keyword_(keyword) -{ - // Set minimum and maximum values - if (keyword_->minimumLimit()) - setMinimum(keyword_->minimumLimit().value()); - if (keyword_->maximumLimit()) - setMaximum(keyword_->maximumLimit().value()); - - // Set current value - setValue(keyword_->data()); - - // Connect the valueChanged signal to our own slot - connect(this, SIGNAL(valueChanged(double)), this, SLOT(spinBoxValueChanged(double))); - - // Set event filtering so that we do not blindly accept mouse wheel events (problematic since we will exist in a - // QScrollArea) - installEventFilter(new MouseWheelWidgetAdjustmentGuard(this)); -} - -/* - * Slots - */ - -// Spin box value changed -void DoubleKeywordWidget::spinBoxValueChanged(double newValue) -{ - if (refreshing_) - return; - - if (keyword_->setData(newValue)) - Q_EMIT(keywordDataChanged(keyword_->editSignals())); -} - -/* - * Update - */ - -// Update value displayed in widget -void DoubleKeywordWidget::updateValue(const Flags &mutationFlags) -{ - refreshing_ = true; - - setValue(keyword_->data()); - - refreshing_ = false; -} diff --git a/src/gui/keywordWidgets/double.h b/src/gui/keywordWidgets/double.h deleted file mode 100644 index f0ad2b73c3..0000000000 --- a/src/gui/keywordWidgets/double.h +++ /dev/null @@ -1,42 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#pragma once - -#include "gui/keywordWidgets/base.h" -#include "gui/widgets/exponentialSpin.h" -#include "keywords/double.h" - -class DoubleKeywordWidget : public ExponentialSpin, public KeywordWidgetBase -{ - // All Qt declarations must include this macro - Q_OBJECT - - public: - DoubleKeywordWidget(QWidget *parent, DoubleKeyword *keyword, const CoreData &coreData); - - /* - * Keyword - */ - private: - // Associated keyword - DoubleKeyword *keyword_; - - /* - * Signals / Slots - */ - private Q_SLOTS: - // Spin box value changed - void spinBoxValueChanged(double newValue); - - Q_SIGNALS: - // Keyword data changed - void keywordDataChanged(int flags); - - /* - * Update - */ - public: - // Update value displayed in widget - void updateValue(const Flags &mutationFlags) override; -}; diff --git a/src/gui/keywordWidgets/dropDown.cpp b/src/gui/keywordWidgets/dropDown.cpp deleted file mode 100644 index 87de760ea1..0000000000 --- a/src/gui/keywordWidgets/dropDown.cpp +++ /dev/null @@ -1,59 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#include "gui/keywordWidgets/dropDown.h" - -KeywordDropDown::KeywordDropDown(QWidget *parent) -{ - ui_.setupUi(this); - - // Connect signals/slots - connect(&dropWidget_, SIGNAL(hidden()), this, SLOT(dropWidgetHidden())); -} - -/* - * Drop Widget - */ - -// Return the drop widget -DropWidget *KeywordDropDown::dropWidget() { return &dropWidget_; } - -/* - * Signals / Slots - */ - -void KeywordDropDown::on_CallDropWidgetButton_clicked(bool checked) -{ - if (!checked) - dropWidget_.hide(); - else - { - QPoint popupPos; - if (parentWidget()) - popupPos = parentWidget()->mapToGlobal(pos() + QPoint(0, height())); - dropWidget_.show(); - dropWidget_.move(popupPos); - } -} - -void KeywordDropDown::dropWidgetHidden() -{ - // Un-check the call button - ui_.CallDropWidgetButton->setChecked(false); - - // Need to store data from widget, in case it has changed - updateKeywordData(); -} - -/* - * Update - */ - -// Set summary text on call button -void KeywordDropDown::setSummaryText(const QString s) { ui_.CallDropWidgetButton->setText(s); } - -// Set icon on call button -void KeywordDropDown::setSummaryIcon(QIcon icon) { ui_.CallDropWidgetButton->setIcon(icon); } - -// Update keyword data based on widget values -void KeywordDropDown::updateKeywordData() {} \ No newline at end of file diff --git a/src/gui/keywordWidgets/dropDown.h b/src/gui/keywordWidgets/dropDown.h deleted file mode 100644 index ad6c0a0230..0000000000 --- a/src/gui/keywordWidgets/dropDown.h +++ /dev/null @@ -1,51 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#pragma once - -#include "gui/keywordWidgets/dropWidget.h" -#include "gui/keywordWidgets/ui_dropDown.h" -#include - -// Forward Declarations -class CoreData; - -class KeywordDropDown : public QWidget -{ - // All Qt declarations must include this macro - Q_OBJECT - - public: - KeywordDropDown(QWidget *parent); - - /* - * UI - */ - private: - // Main form declaration - Ui::KeywordDropDownControlWidget ui_; - // Widget to display as the drop-down - DropWidget dropWidget_; - - public: - // Return the drop widget - DropWidget *dropWidget(); - - /* - * Signals / Slots - */ - private Q_SLOTS: - void on_CallDropWidgetButton_clicked(bool checked); - void dropWidgetHidden(); - - /* - * Update - */ - protected: - // Set summary text on call button - void setSummaryText(const QString s); - // Set icon on call button - void setSummaryIcon(QIcon icon); - // Update keyword data based on widget values - virtual void updateKeywordData(); -}; diff --git a/src/gui/keywordWidgets/dropDown.ui b/src/gui/keywordWidgets/dropDown.ui deleted file mode 100644 index 97dd7e6d26..0000000000 --- a/src/gui/keywordWidgets/dropDown.ui +++ /dev/null @@ -1,66 +0,0 @@ - - - KeywordDropDownControlWidget - - - - 0 - 0 - 94 - 27 - - - - - 10 - - - - Form - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Summary - - - - :/general/icons/options.svg:/general/icons/options.svg - - - - 16 - 16 - - - - true - - - false - - - - - - - - - - diff --git a/src/gui/keywordWidgets/dropWidget.cpp b/src/gui/keywordWidgets/dropWidget.cpp deleted file mode 100644 index 40fe6df759..0000000000 --- a/src/gui/keywordWidgets/dropWidget.cpp +++ /dev/null @@ -1,14 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#include "gui/keywordWidgets/dropWidget.h" -#include - -DropWidget::DropWidget(QWidget *parent) : QWidget(parent, Qt::FramelessWindowHint | Qt::Popup) {} - -/* - * Reimplementations - */ - -// Hide event -void DropWidget::hideEvent(QHideEvent *event) { Q_EMIT(hidden()); } diff --git a/src/gui/keywordWidgets/dropWidget.h b/src/gui/keywordWidgets/dropWidget.h deleted file mode 100644 index 26fdb949d0..0000000000 --- a/src/gui/keywordWidgets/dropWidget.h +++ /dev/null @@ -1,28 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#pragma once - -#include - -class DropWidget : public QWidget -{ - // All Qt declarations must include this macro - Q_OBJECT - - public: - DropWidget(QWidget *parent = nullptr); - - /* - * Reimplementations - */ - private: - // Hide event - void hideEvent(QHideEvent *event); - - /* - * Signals - */ - Q_SIGNALS: - void hidden(); -}; diff --git a/src/gui/keywordWidgets/enumOptions.cpp b/src/gui/keywordWidgets/enumOptions.cpp deleted file mode 100644 index 55f7816b9c..0000000000 --- a/src/gui/keywordWidgets/enumOptions.cpp +++ /dev/null @@ -1,63 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#include "gui/keywordWidgets/enumOptions.h" -#include "gui/helpers/mouseWheelAdjustmentGuard.h" - -EnumOptionsKeywordWidget::EnumOptionsKeywordWidget(QWidget *parent, EnumOptionsBaseKeyword *keyword, const CoreData &coreData) - : QComboBox(parent), KeywordWidgetBase(coreData), keyword_(keyword) -{ - // Get the underlying EnumOptionsBase - const EnumOptionsBase &options = keyword_->baseOptions(); - - refreshing_ = true; - - // Populate the combo with the available keywords - for (auto n = 0; n < options.nOptions(); ++n) - addItem(QString::fromStdString(std::string(options.keywordByIndex(n)))); - setCurrentIndex(keyword_->enumerationByIndex()); - - refreshing_ = false; - - // Turn off editability - setEditable(false); - - // Connect the currentTextChanged signal to our own slot - connect(this, SIGNAL(currentIndexChanged(int)), this, SLOT(comboBoxIndexChanged(int))); - - // Set event filtering so that we do not blindly accept mouse wheel events (problematic since we will exist in a - // QScrollArea) - installEventFilter(new MouseWheelWidgetAdjustmentGuard(this)); -} - -/* - * Signals / Slots - */ - -// Combo box index changed -void EnumOptionsKeywordWidget::comboBoxIndexChanged(int index) -{ - if (refreshing_) - return; - - // Use the virtual EnumOptionsBaseKeyword::setEnumerationByIndex() to set the new option and inform the underlying - // keyword structure that it has been modified - keyword_->setEnumerationByIndex(index); - - Q_EMIT(keywordDataChanged(keyword_->editSignals())); -} - -/* - * Update - */ - -// Update value displayed in widget -void EnumOptionsKeywordWidget::updateValue(const Flags &mutationFlags) -{ - refreshing_ = true; - - // Set the combo box index - setCurrentIndex(keyword_->enumerationByIndex()); - - refreshing_ = false; -} diff --git a/src/gui/keywordWidgets/enumOptions.h b/src/gui/keywordWidgets/enumOptions.h deleted file mode 100644 index a836e08fbb..0000000000 --- a/src/gui/keywordWidgets/enumOptions.h +++ /dev/null @@ -1,42 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#pragma once - -#include "gui/keywordWidgets/base.h" -#include "keywords/enumOptions.h" -#include - -class EnumOptionsKeywordWidget : public QComboBox, public KeywordWidgetBase -{ - // All Qt declarations must include this macro - Q_OBJECT - - public: - EnumOptionsKeywordWidget(QWidget *parent, EnumOptionsBaseKeyword *keyword, const CoreData &coreData); - - /* - * Keyword - */ - private: - // Associated keyword - EnumOptionsBaseKeyword *keyword_; - - /* - * Signals / Slots - */ - private Q_SLOTS: - // Combo box index changed - void comboBoxIndexChanged(int index); - - Q_SIGNALS: - // Keyword data changed - void keywordDataChanged(int flags); - - /* - * Update - */ - public: - // Update value displayed in widget - void updateValue(const Flags &mutationFlags) override; -}; diff --git a/src/gui/keywordWidgets/expressionVariableVector.cpp b/src/gui/keywordWidgets/expressionVariableVector.cpp deleted file mode 100644 index d7d8c6b148..0000000000 --- a/src/gui/keywordWidgets/expressionVariableVector.cpp +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#include "gui/keywordWidgets/expressionVariableVector.h" -#include "classes/coreData.h" -#include "expression/variable.h" -#include "gui/delegates/exponentialSpin.h" - -ExpressionVariableVectorKeywordWidget::ExpressionVariableVectorKeywordWidget(QWidget *parent, - ExpressionVariableVectorKeyword *keyword, - const CoreData &coreData) - : QWidget(parent), KeywordWidgetBase(coreData), keyword_(keyword) -{ - // Create and set up the UI for our widget - ui_.setupUi(this); - - // Set up model - variableModel_.setData(keyword->data(), keyword->parentNode()); - ui_.VariablesTable->setModel(&variableModel_); - - // Connect signals / slots - connect(&variableModel_, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &, const QVector &)), this, - SLOT(modelDataChanged(const QModelIndex &, const QModelIndex &))); - - // Add suitable delegate to the table - ui_.VariablesTable->setItemDelegateForColumn(2, new ExponentialSpinDelegate(this)); -} - -/* - * Widgets - */ - -// Variable data changed -void ExpressionVariableVectorKeywordWidget::modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight) -{ - if (refreshing_) - return; - - Q_EMIT(keywordDataChanged(keyword_->editSignals())); -} - -// Update value displayed in widget -void ExpressionVariableVectorKeywordWidget::updateValue(const Flags &mutationFlags) {} diff --git a/src/gui/keywordWidgets/expressionVariableVector.h b/src/gui/keywordWidgets/expressionVariableVector.h deleted file mode 100644 index ad156c5b1f..0000000000 --- a/src/gui/keywordWidgets/expressionVariableVector.h +++ /dev/null @@ -1,51 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#pragma once - -#include "gui/keywordWidgets/base.h" -#include "gui/keywordWidgets/ui_expressionVariableVector.h" -#include "gui/models/expressionVariableVectorModel.h" -#include "keywords/expressionVariableVector.h" - -// Forward Declarations -class QWidget; - -class ExpressionVariableVectorKeywordWidget : public QWidget, public KeywordWidgetBase -{ - // All Qt declarations must include this macro - Q_OBJECT - - public: - ExpressionVariableVectorKeywordWidget(QWidget *parent, ExpressionVariableVectorKeyword *keyword, const CoreData &coreData); - - /* - * Keyword - */ - private: - // Associated keyword - ExpressionVariableVectorKeyword *keyword_; - - /* - * Widgets - */ - private: - // Main form declaration - Ui::ExpressionVariableVectorWidget ui_; - // Model for table - ExpressionVariableVectorModel variableModel_; - - private Q_SLOTS: - void modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight); - - Q_SIGNALS: - // Keyword data changed - void keywordDataChanged(int flags); - - /* - * Update - */ - public: - // Update value displayed in widget - void updateValue(const Flags &mutationFlags) override; -}; diff --git a/src/gui/keywordWidgets/expressionVariableVector.ui b/src/gui/keywordWidgets/expressionVariableVector.ui deleted file mode 100644 index ada6448ab3..0000000000 --- a/src/gui/keywordWidgets/expressionVariableVector.ui +++ /dev/null @@ -1,60 +0,0 @@ - - - ExpressionVariableVectorWidget - - - - 0 - 0 - 194 - 81 - - - - - 10 - - - - Form - - - - 4 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - - 16777215 - 16777215 - - - - QAbstractItemView::SingleSelection - - - - - - - - diff --git a/src/gui/keywordWidgets/fileAndFormat.cpp b/src/gui/keywordWidgets/fileAndFormat.cpp deleted file mode 100644 index aaf46c0915..0000000000 --- a/src/gui/keywordWidgets/fileAndFormat.cpp +++ /dev/null @@ -1,165 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#include "gui/keywordWidgets/fileAndFormat.h" -#include "gui/keywordWidgets/dialog.h" -#include "gui/models/nodeGraph/enumRegistry.h" -#include "io/fileAndFormat.h" -#include "main/dissolve.h" -#include -#include -#include -#include - -FileAndFormatKeywordWidget::FileAndFormatKeywordWidget(QWidget *parent, FileAndFormatKeyword *keyword, CoreData &coreData) - : QWidget(parent), KeywordWidgetBase(coreData), keyword_(keyword), coreData_(coreData) -{ - ui_.setupUi(this); - - refreshing_ = true; - - // Populate combo with the file formats available - ui_.FormatCombo->clear(); - ui_.FormatCombo->setModel(EnumRegistry::options(typeid(int)).get()); - - // If the FileAndFormat has keyword options, enable the options button. - ui_.OptionsButton->setEnabled(keyword_->hasOptions()); - - // Set current information - updateWidgetValues(coreData_); - - refreshing_ = false; -} - -/* - * Widgets - */ - -void FileAndFormatKeywordWidget::on_FileEdit_editingFinished() -{ - if (refreshing_) - return; - - updateKeywordData(); - - checkFileValidity(); - - Q_EMIT(keywordDataChanged(keyword_->editSignals())); -} - -void FileAndFormatKeywordWidget::on_FileEdit_returnPressed() -{ - if (refreshing_) - return; - - updateKeywordData(); - - checkFileValidity(); - - Q_EMIT(keywordDataChanged(keyword_->editSignals())); -} - -void FileAndFormatKeywordWidget::on_FileSelectButton_clicked(bool checked) -{ - // Grab the target FileAndFormat - auto &fileAndFormat = keyword_->data(); - - // Determine what sort of dialog we need to raise... - QString filename; - QFileInfo fileInfo(QString::fromStdString(std::string(fileAndFormat.filename()))); - if (fileAndFormat.fileMustExist()) - { - // Input File - filename = - QFileDialog::getOpenFileName(this, tr("Select Input File"), fileInfo.absoluteFilePath(), tr("All Files (*)")); - } - else - { - // Output File - filename = - QFileDialog::getSaveFileName(this, tr("Select Output File"), fileInfo.absoluteFilePath(), tr("All Files (*)")); - } - - if (!filename.isEmpty()) - { - // Set relative path to file, using the current input file as the reference point - QFileInfo fileInfo(QString::fromStdString(std::string(coreData_.inputFilename()))); - ui_.FileEdit->setText(fileInfo.dir().relativeFilePath(filename)); - updateKeywordData(); - updateWidgetValues(coreData_); - Q_EMIT(keywordDataChanged(keyword_->editSignals())); - } -} - -void FileAndFormatKeywordWidget::on_FormatCombo_currentIndexChanged(int index) -{ - if (refreshing_) - return; - - updateKeywordData(); - - Q_EMIT(keywordDataChanged(keyword_->editSignals())); -} - -void FileAndFormatKeywordWidget::on_OptionsButton_clicked(bool checked) -{ - KeywordsDialog optionsDialog(this, keyword_->data().keywords(), coreData_); - - optionsDialog.showOptions(); - - if (optionsDialog.keywordsModified()) - Q_EMIT(keywordDataChanged(optionsDialog.keywordSignalMask() + keyword_->editSignals())); -} - -/* - * Update - */ - -// Check / set validity of current filename -void FileAndFormatKeywordWidget::checkFileValidity() -{ - // Grab the target FileAndFormat - const auto &fileAndFormat = keyword_->data(); - - // If this is an export FileAndFormat, no need to show the indicator or check if the file exists - if (fileAndFormat.fileMustExist()) - { - ui_.FileExistsIndicator->setVisible(true); - auto ok = fileAndFormat.hasFilename() ? DissolveSys::fileExists(fileAndFormat.filename()) : false; - ui_.FileExistsIndicator->setOK(ok); - } - else - ui_.FileExistsIndicator->setVisible(false); -} - -// Update value displayed in widget -void FileAndFormatKeywordWidget::updateValue(const Flags &mutationFlags) -{ - updateWidgetValues(coreData_); -} - -// Update widget values data based on keyword data -void FileAndFormatKeywordWidget::updateWidgetValues(const CoreData &coreData) -{ - refreshing_ = true; - - // Grab the target FileAndFormat - auto &fileAndFormat = keyword_->data(); - - // Update widgets - ui_.FileEdit->setText(QString::fromStdString(std::string(fileAndFormat.filename()))); - ui_.FormatCombo->setCurrentIndex(fileAndFormat.formatIndex()); - checkFileValidity(); - - refreshing_ = false; -} - -// Update keyword data based on widget values -void FileAndFormatKeywordWidget::updateKeywordData() -{ - // Grab the target FileAndFormat - auto &fileAndFormat = keyword_->data(); - - fileAndFormat.setFilename(qPrintable(ui_.FileEdit->text())); - fileAndFormat.setFormatByIndex(ui_.FormatCombo->currentIndex()); -} diff --git a/src/gui/keywordWidgets/fileAndFormat.h b/src/gui/keywordWidgets/fileAndFormat.h deleted file mode 100644 index 118dd4b895..0000000000 --- a/src/gui/keywordWidgets/fileAndFormat.h +++ /dev/null @@ -1,62 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#pragma once - -#include "gui/keywordWidgets/base.h" -#include "gui/keywordWidgets/ui_fileAndFormat.h" -#include "keywords/fileAndFormat.h" -#include - -class FileAndFormatKeywordWidget : public QWidget, public KeywordWidgetBase -{ - // All Qt declarations must include this macro - Q_OBJECT - - public: - FileAndFormatKeywordWidget(QWidget *parent, FileAndFormatKeyword *keyword, CoreData &coreData); - - /* - * Keyword - */ - private: - // Associated keyword - FileAndFormatKeyword *keyword_; - - protected: - // mutable coredata source - CoreData &coreData_; - - /* - * Widgets - */ - private: - // Main form declaration - Ui::FileAndFormatWidget ui_; - - private Q_SLOTS: - void on_FileEdit_editingFinished(); - void on_FileEdit_returnPressed(); - void on_FormatCombo_currentIndexChanged(int index); - void on_FileSelectButton_clicked(bool checked); - void on_OptionsButton_clicked(bool checked); - - Q_SIGNALS: - // Keyword data changed - void keywordDataChanged(int flags); - - /* - * Update - */ - private: - // Check / set validity of current filename - void checkFileValidity(); - - public: - // Update value displayed in widget - void updateValue(const Flags &mutationFlags) override; - // Update widget values data based on keyword data - void updateWidgetValues(const CoreData &coreData); - // Update keyword data based on widget values - void updateKeywordData(); -}; diff --git a/src/gui/keywordWidgets/fileAndFormat.ui b/src/gui/keywordWidgets/fileAndFormat.ui deleted file mode 100644 index ef47cd53ef..0000000000 --- a/src/gui/keywordWidgets/fileAndFormat.ui +++ /dev/null @@ -1,138 +0,0 @@ - - - FileAndFormatWidget - - - - 0 - 0 - 309 - 24 - - - - - 3 - 0 - - - - - 10 - - - - Form - - - - 2 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - - - - - - - - - 0 - 0 - - - - - - - - - 0 - 0 - - - - - - - - :/general/icons/open.svg:/general/icons/open.svg - - - - 16 - 16 - - - - - - - - - 0 - 0 - - - - - - - - - 0 - 0 - - - - Options - - - - :/general/icons/options.svg:/general/icons/options.svg - - - - 16 - 16 - - - - Qt::ToolButtonTextBesideIcon - - - - - - - - CheckIndicator - QLabel -
gui/widgets/checkIndicator.h
-
-
- - - - -
diff --git a/src/gui/keywordWidgets/function1D.cpp b/src/gui/keywordWidgets/function1D.cpp deleted file mode 100644 index c062be4694..0000000000 --- a/src/gui/keywordWidgets/function1D.cpp +++ /dev/null @@ -1,153 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#include "gui/keywordWidgets/function1D.h" -#include "gui/keywordWidgets/dropDown.h" -#include -#include - -#define MaxParams 6 - -Function1DKeywordWidget::Function1DKeywordWidget(QWidget *parent, Function1DKeyword *keyword, const CoreData &coreData) - : KeywordDropDown(this), KeywordWidgetBase(coreData), keyword_(keyword) -{ - // Create and set up the UI for our widget in the drop-down's widget container - ui_.setupUi(dropWidget()); - - refreshing_ = true; - - // Grab widget pointers for convenience - spins_ = {ui_.Parameter0Spin, ui_.Parameter1Spin, ui_.Parameter2Spin, - ui_.Parameter3Spin, ui_.Parameter4Spin, ui_.Parameter5Spin}; - labels_ = {ui_.Parameter0Label, ui_.Parameter1Label, ui_.Parameter2Label, - ui_.Parameter3Label, ui_.Parameter4Label, ui_.Parameter5Label}; - - // Set deltas on spinboxes - for (auto *spin : spins_) - spin->setSingleStep(0.01); - - // Grab the target Function1D - auto &function = keyword_->data(); - - // Get relevant function types to show in combo - auto availableFunctions = Functions1D::matchingFunction1D(keyword_->functionProperties()); - if (availableFunctions.empty()) - { - ui_.FunctionCombo->addItem(""); - ui_.FunctionCombo->setEnabled(false); - } - else - { - auto i = 0; - for (auto func : availableFunctions) - { - ui_.FunctionCombo->addItem(QString::fromStdString(Functions1D::forms().keyword(func)), QVariant::fromValue(func)); - if (func == function.form()) - ui_.FunctionCombo->setCurrentIndex(i); - ++i; - } - } - - // Update all widgets - updateWidgetsFromData(); - - // Update summary text - updateSummaryText(); - - refreshing_ = false; - - // Connect signals / slots - connect(ui_.FunctionCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(functionCombo_currentIndexChanged(int))); - for (auto *spin : spins_) - connect(spin, SIGNAL(valueChanged(double)), this, SLOT(parameterSpin_valueChanged(double))); -} - -/* - * Widgets - */ - -// Function type combo changed -void Function1DKeywordWidget::functionCombo_currentIndexChanged(int index) -{ - if (refreshing_) - return; - - updateKeywordData(); - - updateSummaryText(); - - updateWidgetsFromData(); - - Q_EMIT(keywordDataChanged(keyword_->editSignals())); -} - -// Parameter value changed -void Function1DKeywordWidget::parameterSpin_valueChanged(double value) -{ - if (refreshing_) - return; - - updateKeywordData(); - - updateSummaryText(); - - Q_EMIT(keywordDataChanged(keyword_->editSignals())); -} - -/* - * Update - */ - -// Update widgets, including visibility of spins and labels -void Function1DKeywordWidget::updateWidgetsFromData() -{ - refreshing_ = true; - - // Grab the target Function1D - auto &function = keyword_->data(); - - ui_.FunctionCombo->setCurrentIndex(ui_.FunctionCombo->findData(QVariant::fromValue(function.form()))); - - const auto nParams = function.nParameters(); - for (auto n = 0; n < MaxParams; ++n) - { - spins_[n]->setValue(nParams > n ? function.parameters()[n] : 0.0); - labels_[n]->setText(nParams > n ? QString::fromStdString(function.parameterName(n)) : "N/A"); - spins_[n]->setVisible(nParams > n); - labels_[n]->setVisible(nParams > n); - } - - refreshing_ = false; -} - -// Update value displayed in widget -void Function1DKeywordWidget::updateValue(const Flags &mutationFlags) -{ - updateWidgetsFromData(); -} - -// Update keyword data based on widget values -void Function1DKeywordWidget::updateKeywordData() -{ - // Get current data from widgets - auto func = ui_.FunctionCombo->currentData().value(); - std::vector newParams; - for (auto n = 0; n < Functions1D::functionDefinition1D(func).nParameters(); ++n) - newParams.push_back(spins_[n]->value()); - - // Set new data - keyword_->setData({func, newParams}); -} - -// Update summary text -void Function1DKeywordWidget::updateSummaryText() -{ - // Grab the target Function1D - auto &function = keyword_->data(); - - // Summary text on KeywordDropDown button - setSummaryText(QString::fromStdString( - function.nParameters() == 0 - ? Functions1D::forms().keyword(function.form()) - : std::format("{} ({})", Functions1D::forms().keyword(function.form()), function.parameterSummary()))); -} diff --git a/src/gui/keywordWidgets/function1D.h b/src/gui/keywordWidgets/function1D.h deleted file mode 100644 index ffbc244af2..0000000000 --- a/src/gui/keywordWidgets/function1D.h +++ /dev/null @@ -1,60 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#pragma once - -#include "gui/keywordWidgets/base.h" -#include "gui/keywordWidgets/dropDown.h" -#include "gui/keywordWidgets/ui_function1D.h" -#include "keywords/function1D.h" -#include - -class Function1DKeywordWidget : public KeywordDropDown, public KeywordWidgetBase -{ - // All Qt declarations must include this macro - Q_OBJECT - - public: - Function1DKeywordWidget(QWidget *parent, Function1DKeyword *keyword, const CoreData &coreData); - - /* - * Keyword - */ - private: - // Associated keyword - Function1DKeyword *keyword_; - - /* - * Widgets - */ - private: - // Main form declaration - Ui::Function1DWidget ui_; - std::vector spins_; - std::vector labels_; - - private Q_SLOTS: - // Function type combo changed - void functionCombo_currentIndexChanged(int index); - // Parameter value changed - void parameterSpin_valueChanged(double value); - - Q_SIGNALS: - // Keyword data changed - void keywordDataChanged(int flags); - - /* - * Update - */ - private: - // Update widgets, including visibility of spins and labels - void updateWidgetsFromData(); - - public: - // Update value displayed in widget - void updateValue(const Flags &mutationFlags) override; - // Update keyword data based on widget values - void updateKeywordData() override; - // Update summary text - void updateSummaryText(); -}; diff --git a/src/gui/keywordWidgets/function1D.ui b/src/gui/keywordWidgets/function1D.ui deleted file mode 100644 index 1adee78dfc..0000000000 --- a/src/gui/keywordWidgets/function1D.ui +++ /dev/null @@ -1,204 +0,0 @@ - - - Function1DWidget - - - - 0 - 0 - 173 - 206 - - - - - 0 - 0 - - - - - 10 - - - - Form - - - - QLayout::SetFixedSize - - - 0 - - - 0 - - - 0 - - - 0 - - - 4 - - - - - 3 - - - - - - - - 1 - 0 - - - - 5 : - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - 3 - - - - - - - 3 - - - - - - - - 1 - 0 - - - - 0 : - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 1 - 0 - - - - 2 : - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - 3 - - - - - - - 3 - - - - - - - - 2 - 0 - - - - 3 - - - - - - - - 1 - 0 - - - - 1 : - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 1 - 0 - - - - 4 : - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 1 - 0 - - - - 3 : - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - - - - ExponentialSpin - QDoubleSpinBox -
gui/widgets/exponentialSpin.h
-
-
- - -
diff --git a/src/gui/keywordWidgets/integer.cpp b/src/gui/keywordWidgets/integer.cpp deleted file mode 100644 index 3744661f06..0000000000 --- a/src/gui/keywordWidgets/integer.cpp +++ /dev/null @@ -1,52 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#include "gui/keywordWidgets/integer.h" -#include "gui/helpers/mouseWheelAdjustmentGuard.h" - -IntegerKeywordWidget::IntegerKeywordWidget(QWidget *parent, IntegerKeyword *keyword, const CoreData &coreData) - : QSpinBox(parent), KeywordWidgetBase(coreData), keyword_(keyword) -{ - // Set minimum and maximum values - setRange(keyword_->minimumLimit() ? keyword_->minimumLimit().value() : -1e6, - keyword_->maximumLimit() ? keyword_->maximumLimit().value() : 1e6); - - // Set current value - setValue(keyword_->data()); - - // Connect the - connect(this, SIGNAL(valueChanged(int)), this, SLOT(spinBoxValueChanged(int))); - - // Set event filtering so that we do not blindly accept mouse wheel events (problematic since we will exist in a - // QScrollArea) - installEventFilter(new MouseWheelWidgetAdjustmentGuard(this)); -} - -/* - * Signals / Slots - */ - -// Spin box value changed -void IntegerKeywordWidget::spinBoxValueChanged(int newValue) -{ - if (refreshing_) - return; - - keyword_->setData(newValue); - - Q_EMIT(keywordDataChanged(keyword_->editSignals())); -} - -/* - * Update - */ - -// Update value displayed in widget -void IntegerKeywordWidget::updateValue(const Flags &mutationFlags) -{ - refreshing_ = true; - - setValue(keyword_->data()); - - refreshing_ = false; -} diff --git a/src/gui/keywordWidgets/integer.h b/src/gui/keywordWidgets/integer.h deleted file mode 100644 index 1c50ed21cf..0000000000 --- a/src/gui/keywordWidgets/integer.h +++ /dev/null @@ -1,42 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#pragma once - -#include "gui/keywordWidgets/base.h" -#include "keywords/integer.h" -#include - -class IntegerKeywordWidget : public QSpinBox, public KeywordWidgetBase -{ - // All Qt declarations must include this macro - Q_OBJECT - - public: - IntegerKeywordWidget(QWidget *parent, IntegerKeyword *keyword, const CoreData &coreData); - - /* - * Keyword - */ - private: - // Associated keyword - IntegerKeyword *keyword_; - - /* - * Signals / Slots - */ - private Q_SLOTS: - // Spin box value changed - void spinBoxValueChanged(int newValue); - - Q_SIGNALS: - // Keyword data changed - void keywordDataChanged(int flags); - - /* - * Update - */ - public: - // Update value displayed in widget - void updateValue(const Flags &mutationFlags) override; -}; diff --git a/src/gui/keywordWidgets/interactionPotential.cpp b/src/gui/keywordWidgets/interactionPotential.cpp deleted file mode 100644 index dd79965e5b..0000000000 --- a/src/gui/keywordWidgets/interactionPotential.cpp +++ /dev/null @@ -1,95 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#include "gui/keywordWidgets/interactionPotential.h" -#include "gui/models/nodeGraph/enumRegistry.h" -#include "main/dissolve.h" -#include - -InteractionPotentialKeywordWidget::InteractionPotentialKeywordWidget(QWidget *parent, InteractionPotentialBaseKeyword *keyword, - const CoreData &coreData) - : QWidget(parent), KeywordWidgetBase(coreData), keyword_(keyword) -{ - ui_.setupUi(this); - - refreshing_ = true; - - // Populate combo with the available forms - ui_.FormCombo->clear(); - ui_.FormCombo->setModel(EnumRegistry::options(typeid(int)).get()); - - // Set current information - updateWidgetValues(coreData_); - - refreshing_ = false; -} - -/* - * Widgets - */ - -void InteractionPotentialKeywordWidget::on_ParametersEdit_editingFinished() -{ - if (refreshing_) - return; - - if (updateKeywordData()) - Q_EMIT(keywordDataChanged(keyword_->editSignals())); -} - -void InteractionPotentialKeywordWidget::on_ParametersEdit_returnPressed() -{ - if (refreshing_) - return; - - if (updateKeywordData()) - Q_EMIT(keywordDataChanged(keyword_->editSignals())); -} - -void InteractionPotentialKeywordWidget::on_FormCombo_currentIndexChanged(int index) -{ - if (refreshing_) - return; - - updateKeywordData(); - - Q_EMIT(keywordDataChanged(keyword_->editSignals())); -} - -/* - * Update - */ - -// Update value displayed in widget -void InteractionPotentialKeywordWidget::updateValue(const Flags &mutationFlags) -{ - updateWidgetValues(coreData_); -} - -// Update widget values data based on keyword data -void InteractionPotentialKeywordWidget::updateWidgetValues(const CoreData &coreData) -{ - refreshing_ = true; - - // Update widgets - ui_.ParametersEdit->setText(QString::fromStdString(std::string(keyword_->parametersAsString()))); - ui_.FormCombo->setCurrentIndex(keyword_->formByIndex()); - - refreshing_ = false; -} - -// Update keyword data based on widget values, returning if parameters were set successfully -bool InteractionPotentialKeywordWidget::updateKeywordData() -{ - refreshing_ = true; - - keyword_->setFormByIndex(ui_.FormCombo->currentIndex()); - auto parametersOK = keyword_->setParameters(ui_.ParametersEdit->text().toStdString()); - - // We always update the displayed text since some "conversion" or trimming may have been performed - ui_.ParametersEdit->setText(QString::fromStdString(std::string(keyword_->parametersAsString()))); - - refreshing_ = false; - - return parametersOK; -} diff --git a/src/gui/keywordWidgets/interactionPotential.h b/src/gui/keywordWidgets/interactionPotential.h deleted file mode 100644 index 0304532b31..0000000000 --- a/src/gui/keywordWidgets/interactionPotential.h +++ /dev/null @@ -1,55 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#pragma once - -#include "gui/keywordWidgets/base.h" -#include "gui/keywordWidgets/ui_interactionPotential.h" -#include "gui/models/nodeGraph/enumOptionsModel.h" -#include "keywords/interactionPotential.h" -#include - -class InteractionPotentialKeywordWidget : public QWidget, public KeywordWidgetBase -{ - // All Qt declarations must include this macro - Q_OBJECT - - public: - InteractionPotentialKeywordWidget(QWidget *parent, InteractionPotentialBaseKeyword *keyword, const CoreData &coreData); - - /* - * Keyword - */ - private: - // Associated keyword - InteractionPotentialBaseKeyword *keyword_; - - /* - * Widgets - */ - private: - // Main form declaration - Ui::InteractionPotentialWidget ui_; - // Model for functional form options - EnumOptionsModel formModel_; - - private Q_SLOTS: - void on_ParametersEdit_editingFinished(); - void on_ParametersEdit_returnPressed(); - void on_FormCombo_currentIndexChanged(int index); - - Q_SIGNALS: - // Keyword data changed - void keywordDataChanged(int flags); - - /* - * Update - */ - public: - // Update value displayed in widget - void updateValue(const Flags &mutationFlags) override; - // Update widget values data based on keyword data - void updateWidgetValues(const CoreData &coreData); - // Update keyword data based on widget values, returning if parameters were set successfully - bool updateKeywordData(); -}; diff --git a/src/gui/keywordWidgets/interactionPotential.ui b/src/gui/keywordWidgets/interactionPotential.ui deleted file mode 100644 index 48dc722262..0000000000 --- a/src/gui/keywordWidgets/interactionPotential.ui +++ /dev/null @@ -1,69 +0,0 @@ - - - InteractionPotentialWidget - - - - 0 - 0 - 309 - 30 - - - - - 3 - 0 - - - - - 10 - - - - Form - - - - 2 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - - - - - - 0 - 0 - - - - - - - - - - - diff --git a/src/gui/keywordWidgets/isotopologueSet.cpp b/src/gui/keywordWidgets/isotopologueSet.cpp deleted file mode 100644 index 6108960040..0000000000 --- a/src/gui/keywordWidgets/isotopologueSet.cpp +++ /dev/null @@ -1,148 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#include "gui/keywordWidgets/isotopologueSet.h" -#include "classes/coreData.h" -#include "classes/species.h" -#include "gui/delegates/customComboDelegate.h" -#include "gui/delegates/exponentialSpin.h" -#include "gui/delegates/null.h" -#include "gui/keywordWidgets/dropDown.h" -#include "module/module.h" -#include "templates/algorithms.h" - -IsotopologueSetKeywordWidget::IsotopologueSetKeywordWidget(QWidget *parent, IsotopologueSetKeyword *keyword, - const CoreData &coreData) - : KeywordDropDown(this), KeywordWidgetBase(coreData), keyword_(keyword) -{ - // Create and set up the UI for our widget in the drop-down's widget container - ui_.setupUi(dropWidget()); - - // Set up tree - ui_.IsotopologueTree->setItemDelegateForColumn(1, new CustomComboDelegate( - this, &IsotopologueSetKeywordWidget::availableIsotopologueNames)); - ui_.IsotopologueTree->setItemDelegateForColumn(2, new ExponentialSpinDelegate(this, 0.0)); - ui_.IsotopologueTree->setModel(&setModel_); - setModel_.setSourceData(keyword_->data()); - - // Connect signals / slots - connect(&setModel_, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &, const QVector &)), this, - SLOT(modelDataChanged(const QModelIndex &, const QModelIndex &))); - connect(&setModel_, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &, const QVector &)), this, - SLOT(currentItemChanged())); - connect(ui_.AddSpeciesButton, SIGNAL(clicked(bool)), this, SLOT(addSpeciesButton_clicked(bool))); - connect(ui_.AddIsotopologueButton, SIGNAL(clicked(bool)), this, SLOT(addIsotopologueButton_clicked(bool))); - connect(ui_.RemoveButton, SIGNAL(clicked(bool)), this, SLOT(removeButton_clicked(bool))); - connect(ui_.IsotopologueTree->selectionModel(), SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)), this, - SLOT(currentItemChanged())); - - updateSummaryText(); -} - -/* - * Widgets - */ - -// Return valid Isotopologue names for specified model index -std::vector IsotopologueSetKeywordWidget::availableIsotopologueNames(const QModelIndex &index) -{ - // We are expecting to be given a QModelIndex which locates an item representing an Isotopologue - // The column of the provided child model index must therefore be 1 - if (!index.parent().isValid() || index.column() != 1) - throw( - std::runtime_error("IsotopologueSetKeywordWidget::availableIsotopologueNames() - Not a suitable column (!= 1).\n")); - - // Get the parent - const auto &topes = keyword_->data().isotopologues()[index.parent().row()]; - - // Construct valid names list - std::vector validNames = {"Natural"}; - for (auto &tope : topes.species()->isotopologues()) - validNames.emplace_back(std::string(tope->name())); - - return validNames; -} - -void IsotopologueSetKeywordWidget::modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight) -{ - updateSummaryText(); - - Q_EMIT(keywordDataChanged(keyword_->editSignals())); -} - -void IsotopologueSetKeywordWidget::addSpeciesButton_clicked(bool checked) -{ - auto newIndices = setModel_.addMissingSpecies(coreData_.species()); - for (auto &index : newIndices) - ui_.IsotopologueTree->expand(index); -} - -void IsotopologueSetKeywordWidget::addIsotopologueButton_clicked(bool checked) -{ - setModel_.addIsotopologueWeight(ui_.IsotopologueTree->currentIndex()); -} - -void IsotopologueSetKeywordWidget::removeButton_clicked(bool checked) -{ - setModel_.removeIndex(ui_.IsotopologueTree->currentIndex()); -} - -void IsotopologueSetKeywordWidget::currentItemChanged() -{ - // Don't use the 'current' parameter to get the selected index as we may be called from a `dataChanged` connection - auto index = ui_.IsotopologueTree->currentIndex(); - if (!index.isValid()) - { - ui_.RemoveButton->setEnabled(false); - ui_.AddIsotopologueButton->setEnabled(false); - } - else - { - // Remove button is enabled regardless if we have any kind of selection - ui_.RemoveButton->setEnabled(true); - - // Add isotopologue button enabled based on number of isotopologues currently in the root index context - const auto *topes = - setModel_.data(index.parent().isValid() ? index.parent() : index, Qt::UserRole).value(); - assert(topes); - ui_.AddIsotopologueButton->setEnabled(topes->mix().size() < topes->species()->nIsotopologues() + 1); - } -} - -/* - * Update - */ - -// Update value displayed in widget -void IsotopologueSetKeywordWidget::updateValue(const Flags &mutationFlags) -{ - if (mutationFlags.isSet(DissolveSignals::DataMutations::IsotopologuesMutated)) - updateSummaryText(); -} - -// Update summary text -void IsotopologueSetKeywordWidget::updateSummaryText() -{ - std::string text; - auto nNatural = 0; - for (const auto &topes : keyword_->data().isotopologues()) - // Check if this is a completely "natural" specification - if (std::count_if(topes.mix().begin(), topes.mix().end(), [&topes](const auto &isoWeight) - { return isoWeight.first == topes.species()->naturalIsotopologue(); }) == topes.mix().size()) - { - text += std::format("{}{}[Natural]", text.empty() ? "" : ", ", topes.species()->name()); - ++nNatural; - } - else - { - if (topes.mix().size() == 1) - text += std::format("{}{}[{}]", text.empty() ? "" : ", ", topes.species()->name(), - topes.mix().begin()->first->name()); - else - text += std::format("{}{}[{}]", text.empty() ? "" : ", ", topes.species()->name(), - joinStrings(topes.mix(), ", ", [](const auto &isoWeight) - { return std::format("{}={}", isoWeight.first->name(), isoWeight.second); })); - } - - setSummaryText(nNatural == keyword_->data().nSpecies() ? QString("") : QString::fromStdString(text)); -} diff --git a/src/gui/keywordWidgets/isotopologueSet.h b/src/gui/keywordWidgets/isotopologueSet.h deleted file mode 100644 index 4f2516ffb5..0000000000 --- a/src/gui/keywordWidgets/isotopologueSet.h +++ /dev/null @@ -1,60 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#pragma once - -#include "gui/keywordWidgets/base.h" -#include "gui/keywordWidgets/dropDown.h" -#include "gui/keywordWidgets/ui_isotopologueSet.h" -#include "gui/models/isotopologueSetModel.h" -#include "keywords/isotopologueSet.h" -#include - -class IsotopologueSetKeywordWidget : public KeywordDropDown, public KeywordWidgetBase -{ - // All Qt declarations must include this macro - Q_OBJECT - - public: - IsotopologueSetKeywordWidget(QWidget *parent, IsotopologueSetKeyword *keyword, const CoreData &coreData); - - /* - * Keyword - */ - private: - // Associated keyword - IsotopologueSetKeyword *keyword_; - - /* - * Widgets - */ - private: - // Main form declaration - Ui::IsotopologueSetWidget ui_; - // Model for treeview - IsotopologueSetModel setModel_; - - private: - // Return valid Isotopologue names for specified model index - std::vector availableIsotopologueNames(const QModelIndex &index); - - private Q_SLOTS: - void modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight); - void addSpeciesButton_clicked(bool checked); - void addIsotopologueButton_clicked(bool checked); - void removeButton_clicked(bool checked); - void currentItemChanged(); - - Q_SIGNALS: - // Keyword data changed - void keywordDataChanged(int flags); - - /* - * Update - */ - public: - // Update value displayed in widget - void updateValue(const Flags &mutationFlags) override; - // Update summary text - void updateSummaryText(); -}; diff --git a/src/gui/keywordWidgets/isotopologueSet.ui b/src/gui/keywordWidgets/isotopologueSet.ui deleted file mode 100644 index 52252873f9..0000000000 --- a/src/gui/keywordWidgets/isotopologueSet.ui +++ /dev/null @@ -1,166 +0,0 @@ - - - IsotopologueSetWidget - - - - 0 - 0 - 303 - 182 - - - - - 10 - - - - Form - - - - 4 - - - 4 - - - 4 - - - 4 - - - 4 - - - - - 4 - - - - - - 0 - 0 - - - - Add a new isotopologue reference - - - Species - - - - :/general/icons/add.svg:/general/icons/add.svg - - - - 16 - 16 - - - - Qt::ToolButtonTextBesideIcon - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - false - - - - 0 - 0 - - - - Remove the currently-selected isotopologue reference - - - Remove - - - - :/general/icons/remove.svg:/general/icons/remove.svg - - - - 16 - 16 - - - - Qt::ToolButtonTextBesideIcon - - - - - - - false - - - - 0 - 0 - - - - Add a new isotopologue reference - - - Isotopologue - - - - :/general/icons/add.svg:/general/icons/add.svg - - - - 16 - 16 - - - - Qt::ToolButtonTextBesideIcon - - - - - - - - - QAbstractItemView::AnyKeyPressed|QAbstractItemView::DoubleClicked|QAbstractItemView::EditKeyPressed|QAbstractItemView::SelectedClicked - - - QAbstractItemView::SelectRows - - - - - - - - - - diff --git a/src/gui/keywordWidgets/layer.cpp b/src/gui/keywordWidgets/layer.cpp deleted file mode 100644 index 40fb0a130c..0000000000 --- a/src/gui/keywordWidgets/layer.cpp +++ /dev/null @@ -1,72 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#include "gui/keywordWidgets/layer.h" -#include "gui/helpers/mouseWheelAdjustmentGuard.h" - -LayerKeywordWidget::LayerKeywordWidget(QWidget *parent, LayerKeyword *keyword, CoreData &coreData) - : QWidget(parent), KeywordWidgetBase(coreData), keyword_(keyword), coreData_(coreData) -{ - // Setup our UI - ui_.setupUi(this); - - refreshing_ = false; - - ui_.LayerCombo->setModel(&moduleLayersModel_); - updateLayersCombo(); - - // Set event filtering so that we do not blindly accept mouse wheel events (problematic since we will exist in a - // QScrollArea) - ui_.LayerCombo->installEventFilter(new MouseWheelWidgetAdjustmentGuard(ui_.LayerCombo)); -} - -/* - * Widgets - */ - -void LayerKeywordWidget::on_LayerCombo_currentIndexChanged(int index) -{ - if (refreshing_) - return; - - // Get data from the selected item - - if (index == -1) - keyword_->setData(nullptr); - else - keyword_->setData(ui_.LayerCombo->currentData(Qt::UserRole).value()); - - Q_EMIT(keywordDataChanged(keyword_->editSignals())); -} - -void LayerKeywordWidget::on_ClearButton_clicked(bool checked) -{ - if (ui_.LayerCombo->currentIndex() == -1 && !keyword_->data()) - return; - - ui_.LayerCombo->setCurrentIndex(-1); -} - -/* - * Update - */ -void LayerKeywordWidget::updateLayersCombo() -{ - refreshing_ = true; - - moduleLayersModel_.setData(coreData_.processingLayers(), &coreData_); - - // Set current index based on keyword data - auto it = std::find_if(coreData_.processingLayers().begin(), coreData_.processingLayers().end(), - [&](const auto &layer) { return layer.get() == keyword_->data(); }); - ui_.LayerCombo->setCurrentIndex(it == coreData_.processingLayers().end() ? -1 : it - coreData_.processingLayers().begin()); - - refreshing_ = false; -} - -// Update value displayed in widget -void LayerKeywordWidget::updateValue(const Flags &mutationFlags) -{ - if (mutationFlags.isSet(DissolveSignals::ModulesMutated)) - updateLayersCombo(); -} diff --git a/src/gui/keywordWidgets/layer.h b/src/gui/keywordWidgets/layer.h deleted file mode 100644 index a193b32057..0000000000 --- a/src/gui/keywordWidgets/layer.h +++ /dev/null @@ -1,58 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#pragma once - -#include "gui/keywordWidgets/base.h" -#include "gui/keywordWidgets/ui_layer.h" -#include "gui/models/moduleLayersModel.h" -#include "keywords/layer.h" -#include - -class LayerKeywordWidget : public QWidget, public KeywordWidgetBase -{ - // All Qt declarations must include this macro - Q_OBJECT - - public: - LayerKeywordWidget(QWidget *parent, LayerKeyword *keyword, CoreData &coreData); - - /* - * Keyword - */ - private: - // Associated keyword - LayerKeyword *keyword_; - - protected: - // mutable coredata source - CoreData &coreData_; - - /* - * Widgets - */ - private: - // Main form declaration - Ui::LayerKeywordWidget ui_; - // Model for combo box - ModuleLayersModel moduleLayersModel_; - - private Q_SLOTS: - void on_LayerCombo_currentIndexChanged(int index); - void on_ClearButton_clicked(bool checked); - - Q_SIGNALS: - // Keyword data changed - void keywordDataChanged(int flags); - - /* - * Update - */ - private: - // Reset model data - void updateLayersCombo(); - - public: - // Update value displayed in widget - void updateValue(const Flags &mutationFlags) override; -}; diff --git a/src/gui/keywordWidgets/layer.ui b/src/gui/keywordWidgets/layer.ui deleted file mode 100644 index 2b3ae9fd44..0000000000 --- a/src/gui/keywordWidgets/layer.ui +++ /dev/null @@ -1,68 +0,0 @@ - - - LayerKeywordWidget - - - - 0 - 0 - 207 - 25 - - - - Form - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - - - - - Clear selected - - - ... - - - - :/general/icons/general_clear.svg:/general/icons/general_clear.svg - - - - 16 - 16 - - - - - - - - - - - diff --git a/src/gui/keywordWidgets/module.cpp b/src/gui/keywordWidgets/module.cpp deleted file mode 100644 index 6cbdeb9cfc..0000000000 --- a/src/gui/keywordWidgets/module.cpp +++ /dev/null @@ -1,74 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#include "gui/keywordWidgets/module.h" -#include "gui/helpers/mouseWheelAdjustmentGuard.h" - -ModuleKeywordWidget::ModuleKeywordWidget(QWidget *parent, ModuleKeywordBase *keyword, const CoreData &coreData) - : QWidget(parent), KeywordWidgetBase(coreData), keyword_(keyword) -{ - // Setup our UI - ui_.setupUi(this); - - refreshing_ = false; - - ui_.ModuleCombo->setModel(&moduleModel_); - updateAllowedModules(); - - // Set event filtering so that we do not blindly accept mouse wheel events (problematic since we will exist in a - // QScrollArea) - ui_.ModuleCombo->installEventFilter(new MouseWheelWidgetAdjustmentGuard(ui_.ModuleCombo)); -} - -/* - * Widgets - */ - -void ModuleKeywordWidget::on_ModuleCombo_currentIndexChanged(int index) -{ - if (refreshing_) - return; - - // Get data from the selected item - if (index == -1) - keyword_->setData(nullptr); - else - keyword_->setData(ui_.ModuleCombo->currentData(Qt::UserRole).value()); - - Q_EMIT(keywordDataChanged(keyword_->editSignals())); -} - -void ModuleKeywordWidget::on_ClearButton_clicked(bool checked) -{ - if (ui_.ModuleCombo->currentIndex() == -1 && !keyword_->module()) - return; - - ui_.ModuleCombo->setCurrentIndex(-1); -} - -/* - * Update - */ - -// Check / update allowed modules and displayed data -void ModuleKeywordWidget::updateAllowedModules() -{ - refreshing_ = true; - - // Update allowed modules - allowedModules_ = coreData_.allOfType(keyword_->moduleType()); - moduleModel_.setData(allowedModules_); - - // Set current index based on keyword data - auto it = std::find(allowedModules_.begin(), allowedModules_.end(), keyword_->module()); - ui_.ModuleCombo->setCurrentIndex(it == allowedModules_.end() ? -1 : it - allowedModules_.begin()); - - refreshing_ = false; -} - -// Update value displayed in widget -void ModuleKeywordWidget::updateValue(const Flags &mutationFlags) -{ - if (mutationFlags.isSet(DissolveSignals::ModulesMutated)) - updateAllowedModules(); -} diff --git a/src/gui/keywordWidgets/module.h b/src/gui/keywordWidgets/module.h deleted file mode 100644 index 176046772f..0000000000 --- a/src/gui/keywordWidgets/module.h +++ /dev/null @@ -1,56 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#pragma once - -#include "gui/keywordWidgets/base.h" -#include "gui/keywordWidgets/ui_module.h" -#include "gui/models/moduleModel.h" -#include "keywords/module.h" -#include - -class ModuleKeywordWidget : public QWidget, public KeywordWidgetBase -{ - // All Qt declarations must include this macro - Q_OBJECT - - public: - ModuleKeywordWidget(QWidget *parent, ModuleKeywordBase *keyword, const CoreData &coreData); - - /* - * Keyword - */ - private: - // Associated keyword - ModuleKeywordBase *keyword_; - - /* - * Widgets - */ - private: - // Main form declaration - Ui::ModuleWidget ui_; - // Vector of allowed module targets - std::vector allowedModules_; - // Model for combo box - ModuleModel moduleModel_; - - private Q_SLOTS: - void on_ModuleCombo_currentIndexChanged(int index); - void on_ClearButton_clicked(bool checked); - - Q_SIGNALS: - // Keyword data changed - void keywordDataChanged(int flags); - - /* - * Update - */ - private: - // Check / update allowed modules and displayed data - void updateAllowedModules(); - - public: - // Update value displayed in widget - void updateValue(const Flags &mutationFlags) override; -}; diff --git a/src/gui/keywordWidgets/module.ui b/src/gui/keywordWidgets/module.ui deleted file mode 100644 index a7510f62ad..0000000000 --- a/src/gui/keywordWidgets/module.ui +++ /dev/null @@ -1,79 +0,0 @@ - - - ModuleWidget - - - - 0 - 0 - 207 - 29 - - - - - 0 - 0 - - - - - 10 - - - - Form - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - - - - - Clear selected - - - ... - - - - :/general/icons/clear.svg:/general/icons/clear.svg - - - - 16 - 16 - - - - - - - - - - - diff --git a/src/gui/keywordWidgets/moduleVector.cpp b/src/gui/keywordWidgets/moduleVector.cpp deleted file mode 100644 index b58f744a9b..0000000000 --- a/src/gui/keywordWidgets/moduleVector.cpp +++ /dev/null @@ -1,79 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#include "gui/keywordWidgets/moduleVector.h" -#include "classes/coreData.h" -#include "gui/keywordWidgets/dropDown.h" -#include "module/module.h" -#include "templates/algorithms.h" -#include -#include -#include - -ModuleVectorKeywordWidget::ModuleVectorKeywordWidget(QWidget *parent, ModuleVectorKeyword *keyword, const CoreData &coreData) - : KeywordDropDown(this), KeywordWidgetBase(coreData), keyword_(keyword) -{ - // Create and set up the UI for our widget in the drop-down's widget container - ui_.setupUi(dropWidget()); - - // Set up the model - ui_.ModuleList->setModel(&moduleModel_); - moduleModel_.setCheckStateData(keyword_->data()); - resetModelData(); - - // Connect signals / slots - connect(&moduleModel_, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), this, - SLOT(modelDataChanged(const QModelIndex &, const QModelIndex &))); - - updateSummaryText(); -} - -/* - * Widgets - */ - -// List item changed -void ModuleVectorKeywordWidget::modelDataChanged(const QModelIndex &, const QModelIndex &) -{ - if (refreshing_) - return; - - updateSummaryText(); - - Q_EMIT(keywordDataChanged(keyword_->editSignals())); -} - -/* - * Update - */ - -// Reset model data -void ModuleVectorKeywordWidget::resetModelData() -{ - refreshing_ = true; - - // Update allowed modules - allowedModules_ = coreData_.allOfType(keyword_->moduleTypes()); - moduleModel_.setData(allowedModules_); - - updateSummaryText(); - - refreshing_ = false; -} - -// Update value displayed in widget -void ModuleVectorKeywordWidget::updateValue(const Flags &mutationFlags) -{ - if (mutationFlags.isSet(DissolveSignals::ModulesMutated)) - resetModelData(); -} - -// Update summary text -void ModuleVectorKeywordWidget::updateSummaryText() -{ - if (keyword_->data().empty()) - setSummaryText(""); - else - setSummaryText( - QString::fromStdString(joinStrings(keyword_->data(), ", ", [](const auto &module) { return module->name(); }))); -} diff --git a/src/gui/keywordWidgets/moduleVector.h b/src/gui/keywordWidgets/moduleVector.h deleted file mode 100644 index 41b5681656..0000000000 --- a/src/gui/keywordWidgets/moduleVector.h +++ /dev/null @@ -1,61 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#pragma once - -#include "gui/keywordWidgets/base.h" -#include "gui/keywordWidgets/dropDown.h" -#include "gui/keywordWidgets/ui_moduleVector.h" -#include "gui/models/moduleModel.h" -#include "keywords/moduleVector.h" -#include - -// Forward Declarations -class Module; - -class ModuleVectorKeywordWidget : public KeywordDropDown, public KeywordWidgetBase -{ - // All Qt declarations must include this macro - Q_OBJECT - - public: - ModuleVectorKeywordWidget(QWidget *parent, ModuleVectorKeyword *keyword, const CoreData &coreData); - - /* - * Keyword - */ - private: - // Associated keyword - ModuleVectorKeyword *keyword_; - - /* - * Widgets - */ - private: - // Main form declaration - Ui::ModuleVectorWidget ui_; - // Vector of allowed module targets - std::vector allowedModules_; - // Model for combo box - ModuleModel moduleModel_; - - private Q_SLOTS: - void modelDataChanged(const QModelIndex &, const QModelIndex &); - - Q_SIGNALS: - // Keyword data changed - void keywordDataChanged(int flags); - - /* - * Update - */ - private: - // Reset model data - void resetModelData(); - - public: - // Update value displayed in widget - void updateValue(const Flags &mutationFlags) override; - // Update summary text - void updateSummaryText(); -}; diff --git a/src/gui/keywordWidgets/moduleVector.ui b/src/gui/keywordWidgets/moduleVector.ui deleted file mode 100644 index 11fb5a88cf..0000000000 --- a/src/gui/keywordWidgets/moduleVector.ui +++ /dev/null @@ -1,44 +0,0 @@ - - - ModuleVectorWidget - - - - 0 - 0 - 144 - 218 - - - - - 10 - - - - Form - - - - 0 - - - 0 - - - 0 - - - 0 - - - 4 - - - - - - - - - diff --git a/src/gui/keywordWidgets/node.cpp b/src/gui/keywordWidgets/node.cpp deleted file mode 100644 index 6b7dadaf8b..0000000000 --- a/src/gui/keywordWidgets/node.cpp +++ /dev/null @@ -1,69 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#include "gui/keywordWidgets/node.h" -#include "gui/helpers/mouseWheelAdjustmentGuard.h" - -NodeKeywordWidget::NodeKeywordWidget(QWidget *parent, NodeKeywordBase *keyword, const CoreData &coreData) - : QWidget(parent), KeywordWidgetBase(coreData), keyword_(keyword) -{ - // Setup our UI - ui_.setupUi(this); - ui_.NodeCombo->setModel(&nodeModel_); - - refreshing_ = true; - - // Get allowed nodes, set model for combo box, and set current index - allowedNodes_ = keyword_->allowedNodes(); - nodeModel_.setData(allowedNodes_); - auto it = std::find_if(allowedNodes_.begin(), allowedNodes_.end(), - [&](const auto &node) { return node.get() == keyword_->baseNode().get(); }); - ui_.NodeCombo->setCurrentIndex(it == allowedNodes_.end() ? -1 : it - allowedNodes_.begin()); - - // Set event filtering so that we do not blindly accept mouse wheel events (problematic since we will exist in a - // QScrollArea) - ui_.NodeCombo->installEventFilter(new MouseWheelWidgetAdjustmentGuard(ui_.NodeCombo)); - - refreshing_ = false; -} - -/* - * Widgets - */ - -void NodeKeywordWidget::on_NodeCombo_currentIndexChanged(int index) -{ - if (refreshing_) - return; - - // Get data from the selected item - if (index == -1) - keyword_->setData(nullptr); - else - keyword_->setData(allowedNodes_[ui_.NodeCombo->currentIndex()]); - - Q_EMIT(keywordDataChanged(keyword_->editSignals())); -} - -void NodeKeywordWidget::on_ClearButton_clicked(bool checked) -{ - if (ui_.NodeCombo->currentIndex() == -1 && !keyword_->baseNode()) - return; - - ui_.NodeCombo->setCurrentIndex(-1); -} - -/* - * Update - */ - -// Update value displayed in widget -void NodeKeywordWidget::updateValue(const Flags &mutationFlags) -{ - refreshing_ = true; - - auto it = std::find(allowedNodes_.begin(), allowedNodes_.end(), keyword_->baseNode()); - ui_.NodeCombo->setCurrentIndex(it == allowedNodes_.end() ? -1 : it - allowedNodes_.begin()); - - refreshing_ = false; -} diff --git a/src/gui/keywordWidgets/node.h b/src/gui/keywordWidgets/node.h deleted file mode 100644 index 39c4ab4bca..0000000000 --- a/src/gui/keywordWidgets/node.h +++ /dev/null @@ -1,52 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#pragma once - -#include "gui/keywordWidgets/base.h" -#include "gui/keywordWidgets/ui_node.h" -#include "gui/models/generatorNodeModel.h" -#include "keywords/node.h" -#include - -class NodeKeywordWidget : public QWidget, public KeywordWidgetBase -{ - // All Qt declarations must include this macro - Q_OBJECT - - public: - NodeKeywordWidget(QWidget *parent, NodeKeywordBase *keyword, const CoreData &coreData); - - /* - * Keyword - */ - private: - // Associated keyword - NodeKeywordBase *keyword_; - - /* - * Widgets - */ - private: - // Main form declaration - Ui::NodeWidget ui_; - // Allowed nodes to display in the model - std::vector allowedNodes_; - // Model for the node list - GeneratorNodeModel nodeModel_; - - private Q_SLOTS: - void on_NodeCombo_currentIndexChanged(int index); - void on_ClearButton_clicked(bool checked); - - Q_SIGNALS: - // Keyword data changed - void keywordDataChanged(int flags); - - /* - * Update - */ - public: - // Update value displayed in widget - void updateValue(const Flags &mutationFlags) override; -}; diff --git a/src/gui/keywordWidgets/node.ui b/src/gui/keywordWidgets/node.ui deleted file mode 100644 index 479844ff92..0000000000 --- a/src/gui/keywordWidgets/node.ui +++ /dev/null @@ -1,79 +0,0 @@ - - - NodeWidget - - - - 0 - 0 - 207 - 29 - - - - - 0 - 0 - - - - - 10 - - - - Form - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - - - - - Clear selected - - - ... - - - - :/general/icons/clear.svg:/general/icons/clear.svg - - - - 16 - 16 - - - - - - - - - - - diff --git a/src/gui/keywordWidgets/nodeValue.cpp b/src/gui/keywordWidgets/nodeValue.cpp deleted file mode 100644 index 0a81a7de4d..0000000000 --- a/src/gui/keywordWidgets/nodeValue.cpp +++ /dev/null @@ -1,62 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#include "gui/keywordWidgets/nodeValue.h" - -NodeValueKeywordWidget::NodeValueKeywordWidget(QWidget *parent, NodeValueKeyword *keyword, const CoreData &coreData) - : QWidget(parent), KeywordWidgetBase(coreData), keyword_(keyword) -{ - // Setup our UI - ui_.setupUi(this); - - refreshing_ = true; - - // Set expression text - ui_.ValueEdit->setText(QString::fromStdString(keyword_->data().asString())); - checkValueValidity(); - - refreshing_ = false; -} - -/* - * Widgets - */ - -void NodeValueKeywordWidget::on_ValueEdit_editingFinished() -{ - if (refreshing_) - return; - - keyword_->setData(qPrintable(ui_.ValueEdit->text())); - checkValueValidity(); - - Q_EMIT(keywordDataChanged(keyword_->editSignals())); -} - -void NodeValueKeywordWidget::on_ValueEdit_returnPressed() -{ - if (refreshing_) - return; - - keyword_->setData(qPrintable(ui_.ValueEdit->text())); - checkValueValidity(); - - Q_EMIT(keywordDataChanged(keyword_->editSignals())); -} - -/* - * Update - */ - -// Check validity of current value -void NodeValueKeywordWidget::checkValueValidity() { ui_.ValueValidIndicator->setOK(keyword_->data().isValid()); } - -// Update value displayed in widget -void NodeValueKeywordWidget::updateValue(const Flags &mutationFlags) -{ - refreshing_ = true; - - ui_.ValueEdit->setText(QString::fromStdString(keyword_->data().asString())); - - refreshing_ = false; -} diff --git a/src/gui/keywordWidgets/nodeValue.h b/src/gui/keywordWidgets/nodeValue.h deleted file mode 100644 index 92c519a5f8..0000000000 --- a/src/gui/keywordWidgets/nodeValue.h +++ /dev/null @@ -1,52 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#pragma once - -#include "gui/keywordWidgets/base.h" -#include "gui/keywordWidgets/ui_nodeValue.h" -#include "keywords/nodeValue.h" -#include - -class NodeValueKeywordWidget : public QWidget, public KeywordWidgetBase -{ - // All Qt declarations must include this macro - Q_OBJECT - - public: - NodeValueKeywordWidget(QWidget *parent, NodeValueKeyword *keyword, const CoreData &coreData); - - /* - * Keyword - */ - private: - // Associated keyword - NodeValueKeyword *keyword_; - - /* - * Widgets - */ - private: - // Main form declaration - Ui::NodeValueWidget ui_; - - private Q_SLOTS: - // Value edited - void on_ValueEdit_editingFinished(); - void on_ValueEdit_returnPressed(); - - Q_SIGNALS: - // Keyword data changed - void keywordDataChanged(int flags); - - /* - * Update - */ - private: - // Check validity of current value - void checkValueValidity(); - - public: - // Update value displayed in widget - void updateValue(const Flags &mutationFlags) override; -}; diff --git a/src/gui/keywordWidgets/nodeValue.ui b/src/gui/keywordWidgets/nodeValue.ui deleted file mode 100644 index 2fd5f45dad..0000000000 --- a/src/gui/keywordWidgets/nodeValue.ui +++ /dev/null @@ -1,72 +0,0 @@ - - - NodeValueWidget - - - - 0 - 0 - 207 - 29 - - - - - 0 - 0 - - - - - 10 - - - - Form - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - - 0 - 0 - - - - - - - - - - - - CheckIndicator - QLabel -
gui/widgets/checkIndicator.h
-
-
- - - - -
diff --git a/src/gui/keywordWidgets/nodeValueEnumOptions.cpp b/src/gui/keywordWidgets/nodeValueEnumOptions.cpp deleted file mode 100644 index 77540cb7c2..0000000000 --- a/src/gui/keywordWidgets/nodeValueEnumOptions.cpp +++ /dev/null @@ -1,92 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#include "gui/keywordWidgets/nodeValueEnumOptions.h" -#include "gui/helpers/mouseWheelAdjustmentGuard.h" - -NodeValueEnumOptionsKeywordWidget::NodeValueEnumOptionsKeywordWidget(QWidget *parent, NodeValueEnumOptionsBaseKeyword *keyword, - const CoreData &coreData) - : QWidget(parent), KeywordWidgetBase(coreData), keyword_(keyword) -{ - // Setup our UI - ui_.setupUi(this); - - refreshing_ = true; - - // Get the underlying EnumOptionsBase - const EnumOptionsBase &options = keyword_->baseOptions(); - - // Populate the combo with the available keywords - for (int n = 0; n < options.nOptions(); ++n) - { - ui_.OptionsCombo->addItem(QString::fromStdString(std::string(options.keywordByIndex(n)))); - if (keyword_->enumerationIndex() == n) - ui_.OptionsCombo->setCurrentIndex(n); - } - - // Set expression text - ui_.ValueEdit->setText(QString::fromStdString(keyword_->value().asString())); - checkValueValidity(); - - // Set event filtering on the combo so that we do not blindly accept mouse wheel events (problematic since we - // will exist in a QScrollArea) - ui_.OptionsCombo->installEventFilter(new MouseWheelWidgetAdjustmentGuard(ui_.OptionsCombo)); - - refreshing_ = false; -} - -/* - * Widgets - */ - -void NodeValueEnumOptionsKeywordWidget::on_ValueEdit_editingFinished() -{ - if (refreshing_) - return; - - keyword_->setValue(qPrintable(ui_.ValueEdit->text())); - checkValueValidity(); - - Q_EMIT(keywordDataChanged(keyword_->editSignals())); -} - -void NodeValueEnumOptionsKeywordWidget::on_ValueEdit_returnPressed() -{ - if (refreshing_) - return; - - keyword_->setValue(qPrintable(ui_.ValueEdit->text())); - checkValueValidity(); - - Q_EMIT(keywordDataChanged(keyword_->editSignals())); -} - -void NodeValueEnumOptionsKeywordWidget::on_OptionsCombo_currentIndexChanged(int index) -{ - if (refreshing_) - return; - - keyword_->setEnumeration(index); - - Q_EMIT(keywordDataChanged(keyword_->editSignals())); -} - -/* - * Update - */ - -// Check validity of current value -void NodeValueEnumOptionsKeywordWidget::checkValueValidity() { ui_.ValueValidIndicator->setOK(keyword_->value().isValid()); } - -// Update value displayed in widget -void NodeValueEnumOptionsKeywordWidget::updateValue(const Flags &mutationFlags) -{ - refreshing_ = true; - - ui_.ValueEdit->setText(QString::fromStdString(keyword_->value().asString())); - ui_.OptionsCombo->setCurrentIndex(keyword_->enumerationIndex()); - - checkValueValidity(); - - refreshing_ = false; -} diff --git a/src/gui/keywordWidgets/nodeValueEnumOptions.h b/src/gui/keywordWidgets/nodeValueEnumOptions.h deleted file mode 100644 index 056b0927c6..0000000000 --- a/src/gui/keywordWidgets/nodeValueEnumOptions.h +++ /dev/null @@ -1,51 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#pragma once - -#include "gui/keywordWidgets/base.h" -#include "gui/keywordWidgets/ui_nodeValueEnumOptions.h" -#include "keywords/nodeValueEnumOptions.h" -#include - -class NodeValueEnumOptionsKeywordWidget : public QWidget, public KeywordWidgetBase -{ - // All Qt declarations must include this macro - Q_OBJECT - - public: - NodeValueEnumOptionsKeywordWidget(QWidget *parent, NodeValueEnumOptionsBaseKeyword *keyword, const CoreData &coreData); - - /* - * Keyword - */ - private: - // Associated keyword - NodeValueEnumOptionsBaseKeyword *keyword_; - - /* - * Widgets - */ - private: - // Main form declaration - Ui::NodeValueEnumOptionsWidget ui_; - - private Q_SLOTS: - // Value edited - void on_ValueEdit_editingFinished(); - void on_ValueEdit_returnPressed(); - void on_OptionsCombo_currentIndexChanged(int index); - - Q_SIGNALS: - // Keyword data changed - void keywordDataChanged(int flags); - - /* - * Update - */ - public: - // Check validity of current value - void checkValueValidity(); - // Update value displayed in widget - void updateValue(const Flags &mutationFlags) override; -}; diff --git a/src/gui/keywordWidgets/nodeValueEnumOptions.ui b/src/gui/keywordWidgets/nodeValueEnumOptions.ui deleted file mode 100644 index 137647c3e9..0000000000 --- a/src/gui/keywordWidgets/nodeValueEnumOptions.ui +++ /dev/null @@ -1,75 +0,0 @@ - - - NodeValueEnumOptionsWidget - - - - 0 - 0 - 207 - 29 - - - - - 0 - 0 - - - - - 10 - - - - Form - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - - - - - 0 - 0 - - - - - - - - - - - - CheckIndicator - QLabel -
gui/widgets/checkIndicator.h
-
-
- - - - -
diff --git a/src/gui/keywordWidgets/nodeVector.cpp b/src/gui/keywordWidgets/nodeVector.cpp deleted file mode 100644 index 01fe11988a..0000000000 --- a/src/gui/keywordWidgets/nodeVector.cpp +++ /dev/null @@ -1,73 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#include "gui/keywordWidgets/nodeVector.h" -#include "classes/coreData.h" -#include "generator/generator.h" -#include "templates/algorithms.h" -#include - -NodeVectorKeywordWidget::NodeVectorKeywordWidget(QWidget *parent, NodeVectorKeywordBase *keyword, const CoreData &coreData) - : KeywordDropDown(this), KeywordWidgetBase(coreData), keyword_(keyword) -{ - // Create and set up the UI for our widget in the drop-down's widget container - ui_.setupUi(dropWidget()); - - // Set up the model - ui_.NodeList->setModel(&nodeModel_); - allowedNodes_ = keyword_->allowedNodes(); - nodeModel_.setNodeSelectedFunction([&](ConstNodeRef node) { return keyword_->addNode(node); }); - nodeModel_.setNodeDeselectedFunction([&](ConstNodeRef node) { return keyword_->removeNode(node); }); - nodeModel_.setNodePresenceFunction([&](ConstNodeRef node) { return keyword_->isPresent(node); }); - resetModelData(); - - // Connect signals / slots - connect(&nodeModel_, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), this, - SLOT(modelDataChanged(const QModelIndex &, const QModelIndex &))); - - // Summary text on KeywordDropDown button - setSummaryText("Edit..."); -} - -/* - * Widgets - */ - -void NodeVectorKeywordWidget::modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight) -{ - if (refreshing_) - return; - - updateSummaryText(); - - Q_EMIT(keywordDataChanged(keyword_->editSignals())); -} - -/* - * Update - */ - -// Reset model data -void NodeVectorKeywordWidget::resetModelData() -{ - refreshing_ = true; - - nodeModel_.setData(allowedNodes_); - - updateSummaryText(); - - refreshing_ = false; -} - -// Update value displayed in widget -void NodeVectorKeywordWidget::updateValue(const Flags &mutationFlags) { resetModelData(); } - -// Update summary text -void NodeVectorKeywordWidget::updateSummaryText() -{ - auto nodes{keyword_->nodes()}; - if (nodes.empty()) - setSummaryText(""); - else - setSummaryText(QString::fromStdString(joinStrings(nodes, ", ", [](const auto &node) { return node->name(); }))); -} diff --git a/src/gui/keywordWidgets/nodeVector.h b/src/gui/keywordWidgets/nodeVector.h deleted file mode 100644 index c8871c2468..0000000000 --- a/src/gui/keywordWidgets/nodeVector.h +++ /dev/null @@ -1,58 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#pragma once - -#include "gui/keywordWidgets/base.h" -#include "gui/keywordWidgets/dropDown.h" -#include "gui/keywordWidgets/ui_nodeVector.h" -#include "gui/models/generatorNodeModel.h" -#include "keywords/nodeVector.h" -#include - -class NodeVectorKeywordWidget : public KeywordDropDown, public KeywordWidgetBase -{ - // All Qt declarations must include this macro - Q_OBJECT - - public: - NodeVectorKeywordWidget(QWidget *parent, NodeVectorKeywordBase *keyword, const CoreData &coreData); - - /* - * Keyword - */ - private: - // Associated keyword - NodeVectorKeywordBase *keyword_; - - /* - * Widgets - */ - private: - // Main form declaration - Ui::NodeRefListWidget ui_; - // Allowed nodes to display in the model - std::vector allowedNodes_; - // Model for the node list - GeneratorNodeModel nodeModel_; - - private Q_SLOTS: - void modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight); - - Q_SIGNALS: - // Keyword data changed - void keywordDataChanged(int flags); - - /* - * Update - */ - private: - // Reset model data - void resetModelData(); - - public: - // Update value displayed in widget - void updateValue(const Flags &mutationFlags) override; - // Update summary text - void updateSummaryText(); -}; diff --git a/src/gui/keywordWidgets/nodeVector.ui b/src/gui/keywordWidgets/nodeVector.ui deleted file mode 100644 index 7ea6c11eba..0000000000 --- a/src/gui/keywordWidgets/nodeVector.ui +++ /dev/null @@ -1,52 +0,0 @@ - - - NodeRefListWidget - - - - 0 - 0 - 264 - 200 - - - - - 0 - 0 - - - - - 10 - - - - Form - - - - 4 - - - 4 - - - 4 - - - 4 - - - 4 - - - - - - - - - - - diff --git a/src/gui/keywordWidgets/optionalDouble.cpp b/src/gui/keywordWidgets/optionalDouble.cpp deleted file mode 100644 index c260e59b3e..0000000000 --- a/src/gui/keywordWidgets/optionalDouble.cpp +++ /dev/null @@ -1,68 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#include "gui/keywordWidgets/optionalDouble.h" -#include "gui/helpers/mouseWheelAdjustmentGuard.h" - -OptionalDoubleKeywordWidget::OptionalDoubleKeywordWidget(QWidget *parent, OptionalDoubleKeyword *keyword, - const CoreData &coreData) - : ExponentialSpin(parent), KeywordWidgetBase(coreData), keyword_(keyword) -{ - // Set minimum and maximum values and step size - setMinimum(keyword_->minimumLimit()); - if (keyword_->maximumLimit()) - setMaximum(keyword_->maximumLimit().value()); - setSingleStep(keyword_->valueDelta()); - - // Set null value text - setSpecialValueText(QString::fromStdString(keyword_->textWhenNull())); - - // Set current value - setValue(keyword_->data()); - - // Connect signals - connect(this, SIGNAL(valueChanged(double)), this, SLOT(spinBoxValueChanged(double))); - connect(this, SIGNAL(valueNullified()), this, SLOT(spinBoxValueNullified())); - - // Set event filtering so that we do not blindly accept mouse wheel events (problematic since we will exist in a - // QScrollArea) - installEventFilter(new MouseWheelWidgetAdjustmentGuard(this)); -} - -/* - * Slots - */ - -// Spin box value changed -void OptionalDoubleKeywordWidget::spinBoxValueChanged(double newValue) -{ - if (refreshing_) - return; - - if (keyword_->setData(newValue)) - Q_EMIT(keywordDataChanged(keyword_->editSignals())); -} - -// Spin box value nullified -void OptionalDoubleKeywordWidget::spinBoxValueNullified() -{ - if (refreshing_ || !keyword_->data()) - return; - - keyword_->setData(std::nullopt); - Q_EMIT(keywordDataChanged(keyword_->editSignals())); -} - -/* - * Update - */ - -// Update value displayed in widget -void OptionalDoubleKeywordWidget::updateValue(const Flags &mutationFlags) -{ - refreshing_ = true; - - setValue(keyword_->data()); - - refreshing_ = false; -} diff --git a/src/gui/keywordWidgets/optionalDouble.h b/src/gui/keywordWidgets/optionalDouble.h deleted file mode 100644 index dfa7557eae..0000000000 --- a/src/gui/keywordWidgets/optionalDouble.h +++ /dev/null @@ -1,44 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#pragma once - -#include "gui/keywordWidgets/base.h" -#include "gui/widgets/exponentialSpin.h" -#include "keywords/optionalDouble.h" - -class OptionalDoubleKeywordWidget : public ExponentialSpin, public KeywordWidgetBase -{ - // All Qt declarations must include this macro - Q_OBJECT - - public: - OptionalDoubleKeywordWidget(QWidget *parent, OptionalDoubleKeyword *keyword, const CoreData &coreData); - - /* - * Keyword - */ - private: - // Associated keyword - OptionalDoubleKeyword *keyword_; - - /* - * Signals / Slots - */ - private Q_SLOTS: - // Spin box value changed - void spinBoxValueChanged(double newValue); - // Spin box value nullified - void spinBoxValueNullified(); - - Q_SIGNALS: - // Keyword data changed - void keywordDataChanged(int flags); - - /* - * Update - */ - public: - // Update value displayed in widget - void updateValue(const Flags &mutationFlags) override; -}; diff --git a/src/gui/keywordWidgets/optionalInt.cpp b/src/gui/keywordWidgets/optionalInt.cpp deleted file mode 100644 index b0bde2573d..0000000000 --- a/src/gui/keywordWidgets/optionalInt.cpp +++ /dev/null @@ -1,68 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#include "gui/keywordWidgets/optionalInt.h" -#include "gui/helpers/mouseWheelAdjustmentGuard.h" - -OptionalIntegerKeywordWidget::OptionalIntegerKeywordWidget(QWidget *parent, OptionalIntegerKeyword *keyword, - const CoreData &coreData) - : IntegerSpin(parent), KeywordWidgetBase(coreData), keyword_(keyword) -{ - // Set minimum and maximum values and step size - setMinimum(keyword_->minimumLimit()); - if (keyword_->maximumLimit()) - setMaximum(keyword_->maximumLimit().value()); - setSingleStep(keyword_->valueDelta()); - - // Set null value text - setSpecialValueText(QString::fromStdString(keyword_->textWhenNull())); - - // Set current value - setValue(keyword_->data()); - - // Connect signals - connect(this, SIGNAL(valueChanged(int)), this, SLOT(spinBoxValueChanged(int))); - connect(this, SIGNAL(valueNullified()), this, SLOT(spinBoxValueNullified())); - - // Set event filtering so that we do not blindly accept mouse wheel events (problematic since we will exist in a - // QScrollArea) - installEventFilter(new MouseWheelWidgetAdjustmentGuard(this)); -} - -/* - * Slots - */ - -// Spin box value changed -void OptionalIntegerKeywordWidget::spinBoxValueChanged(int newValue) -{ - if (refreshing_) - return; - - if (keyword_->setData(newValue)) - Q_EMIT(keywordDataChanged(keyword_->editSignals())); -} - -// Spin box value nullified -void OptionalIntegerKeywordWidget::spinBoxValueNullified() -{ - if (refreshing_ || !keyword_->data()) - return; - - keyword_->setData(std::nullopt); - Q_EMIT(keywordDataChanged(keyword_->editSignals())); -} - -/* - * Update - */ - -// Update value displayed in widget -void OptionalIntegerKeywordWidget::updateValue(const Flags &mutationFlags) -{ - refreshing_ = true; - - setValue(keyword_->data()); - - refreshing_ = false; -} diff --git a/src/gui/keywordWidgets/optionalInt.h b/src/gui/keywordWidgets/optionalInt.h deleted file mode 100644 index 19774d3f04..0000000000 --- a/src/gui/keywordWidgets/optionalInt.h +++ /dev/null @@ -1,44 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#pragma once - -#include "gui/keywordWidgets/base.h" -#include "gui/widgets/integerSpin.h" -#include "keywords/optionalInt.h" - -class OptionalIntegerKeywordWidget : public IntegerSpin, public KeywordWidgetBase -{ - // All Qt declarations must include this macro - Q_OBJECT - - public: - OptionalIntegerKeywordWidget(QWidget *parent, OptionalIntegerKeyword *keyword, const CoreData &coreData); - - /* - * Keyword - */ - private: - // Associated keyword - OptionalIntegerKeyword *keyword_; - - /* - * Signals / Slots - */ - private Q_SLOTS: - // Spin box value changed - void spinBoxValueChanged(int newValue); - // Spin box value nullified - void spinBoxValueNullified(); - - Q_SIGNALS: - // Keyword data changed - void keywordDataChanged(int flags); - - /* - * Update - */ - public: - // Update value displayed in widget - void updateValue(const Flags &mutationFlags) override; -}; diff --git a/src/gui/keywordWidgets/producers.cpp b/src/gui/keywordWidgets/producers.cpp deleted file mode 100644 index 7130bfc5f6..0000000000 --- a/src/gui/keywordWidgets/producers.cpp +++ /dev/null @@ -1,119 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#include "gui/keywordWidgets/producers.h" -#include "gui/keywordWidgets/atomTypeVector.h" -#include "gui/keywordWidgets/base.h" -#include "gui/keywordWidgets/bool.h" -#include "gui/keywordWidgets/configuration.h" -#include "gui/keywordWidgets/configurationVector.h" -#include "gui/keywordWidgets/double.h" -#include "gui/keywordWidgets/dropWidget.h" -#include "gui/keywordWidgets/enumOptions.h" -#include "gui/keywordWidgets/expressionVariableVector.h" -#include "gui/keywordWidgets/fileAndFormat.h" -#include "gui/keywordWidgets/function1D.h" -#include "gui/keywordWidgets/integer.h" -#include "gui/keywordWidgets/interactionPotential.h" -#include "gui/keywordWidgets/isotopologueSet.h" -#include "gui/keywordWidgets/layer.h" -#include "gui/keywordWidgets/module.h" -#include "gui/keywordWidgets/moduleVector.h" -#include "gui/keywordWidgets/node.h" -#include "gui/keywordWidgets/nodeValue.h" -#include "gui/keywordWidgets/nodeValueEnumOptions.h" -#include "gui/keywordWidgets/nodeVector.h" -#include "gui/keywordWidgets/optionalDouble.h" -#include "gui/keywordWidgets/optionalInt.h" -#include "gui/keywordWidgets/range.h" -#include "gui/keywordWidgets/rangeVector.h" -#include "gui/keywordWidgets/species.h" -#include "gui/keywordWidgets/speciesSite.h" -#include "gui/keywordWidgets/speciesSiteVector.h" -#include "gui/keywordWidgets/speciesVector.h" -#include "gui/keywordWidgets/stdString.h" -#include "gui/keywordWidgets/vec3Double.h" -#include "gui/keywordWidgets/vec3Integer.h" -#include "gui/keywordWidgets/vec3NodeValue.h" -#include "gui/keywordWidgets/weightedModuleVector.h" -#include "io/import/data1D.h" -#include "io/import/data2D.h" -#include "io/import/data3D.h" -#include "keywords/dataSource.h" -#include "keywords/elementVector.h" -#include "keywords/expression.h" -#include "keywords/generator.h" -#include "keywords/nodeBranch.h" -#include - -KeywordWidgetProducer::KeywordWidgetProducer() -{ - // Keywords with normal widgets - registerProducer(); - registerProducer(); - registerProducer(); - registerProducer(); - registerProducer(); - registerProducer(); - registerProducer(); - registerProducer(); - registerProducer(); - registerProducer(); - registerProducer(); - registerProducer(); - registerProducer(); - registerProducer(); - registerProducer(); - registerProducer(); - registerProducer(); - registerProducer(); - registerProducer(); - registerProducer(); - registerProducer(); - registerProducer(); - registerProducer(); - registerProducer(); - registerProducer(); - registerProducer(); - registerProducer(); - registerProducer(); - registerProducer(); - registerProducer(); - registerProducer(); - registerProducer(); - - // Keywords with no widgets - registerNullProducer(); - registerNullProducer(); - registerNullProducer(); - registerNullProducer(); - registerNullProducer(); -} - -/* - * Producers - */ - -// Produce object of specified type -std::pair KeywordWidgetProducer::produce(KeywordBase *keyword, CoreData &coreData) const -{ - auto it = producers_.find(keyword->typeIndex()); - if (it == producers_.end()) - Messenger::exception("A producer has not been registered for type '{}' (keyword name is '{}'), so a " - "new widget for this keyword cannot be created.\n", - keyword->typeIndex().name(), keyword->name()); - - return (it->second)(keyword, coreData); -} - -/* - * Instance - */ - -// Return the producer instance -const KeywordWidgetProducer &KeywordWidgetProducer::instance() -{ - static KeywordWidgetProducer instance; - - return instance; -} diff --git a/src/gui/keywordWidgets/producers.h b/src/gui/keywordWidgets/producers.h deleted file mode 100644 index d122f6f6c0..0000000000 --- a/src/gui/keywordWidgets/producers.h +++ /dev/null @@ -1,81 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#pragma once - -#include "keywords/base.h" -#include -#include -#include -#include -#include -#include - -// Forward Declarations -class KeywordWidgetBase; -class QWidget; - -// KeywordWidget Producer -class KeywordWidgetProducer -{ - private: - KeywordWidgetProducer(); - - public: - KeywordWidgetProducer(const KeywordWidgetProducer &) = delete; - KeywordWidgetProducer(KeywordWidgetProducer &&) = delete; - KeywordWidgetProducer &operator=(const KeywordWidgetProducer &) = delete; - KeywordWidgetProducer &operator=(KeywordWidgetProducer &&) = delete; - - /* - * Producers - */ - private: - // Return type - using WidgetKeywordProduct = std::pair; - // Producer function type - using ProducerFunction = std::function; - // Producers for all data types - std::unordered_map producers_; - - private: - // Return widget pair from supplied widget derived class - template WidgetKeywordProduct formProduct(W *keywordWidget) { return {keywordWidget, keywordWidget}; } - // Register producer for specific class - template void registerProducer(ProducerFunction function) { producers_[typeid(K)] = std::move(function); } - template void registerProducer() - { - producers_[typeid(K *)] = [&](KeywordBase *keyword, CoreData &coreData) - { - // Cast the base up to the full keyword - auto *k = dynamic_cast(keyword); - assert(k); - auto *w = new W(nullptr, k, coreData); - return WidgetKeywordProduct{w, w}; - }; - } - template void registerNullProducer() - { - producers_[typeid(K *)] = [&](KeywordBase *keyword, const CoreData &coreData) - { return WidgetKeywordProduct{nullptr, nullptr}; }; - } - // Produce object of specified type - std::pair produce(KeywordBase *keyword, CoreData &coreData) const; - - /* - * Instance - */ - private: - // Return the producer instance - static const KeywordWidgetProducer &instance(); - - /* - * Static Functions - */ - public: - // Create new item via template - static std::pair create(KeywordBase *keyword, CoreData &coreData) - { - return instance().produce(keyword, coreData); - } -}; diff --git a/src/gui/keywordWidgets/range.cpp b/src/gui/keywordWidgets/range.cpp deleted file mode 100644 index 122ca293ca..0000000000 --- a/src/gui/keywordWidgets/range.cpp +++ /dev/null @@ -1,93 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#include "gui/keywordWidgets/range.h" -#include "gui/helpers/mouseWheelAdjustmentGuard.h" -#include "gui/keywordWidgets/vec3Labels.h" - -RangeKeywordWidget::RangeKeywordWidget(QWidget *parent, RangeKeyword *keyword, const CoreData &coreData) - : QWidget(parent), KeywordWidgetBase(coreData), keyword_(keyword) -{ - // Setup our UI - ui_.setupUi(this); - - refreshing_ = true; - - // Set minimum and maximum values - if (keyword_->minimumLimit()) - { - ui_.Spin1->setMinimum(keyword_->minimumLimit().value()); - ui_.Spin2->setMinimum(keyword_->minimumLimit().value()); - } - if (keyword_->maximumLimit()) - { - ui_.Spin1->setMaximum(keyword_->maximumLimit().value()); - ui_.Spin2->setMaximum(keyword_->maximumLimit().value()); - } - - // Set current values - ui_.Spin1->setValue(keyword_->data().minimum()); - ui_.Spin2->setValue(keyword_->data().maximum()); - - // Set event filtering so that we do not blindly accept mouse wheel events (problematic since we will exist in a - // QScrollArea) - ui_.Spin1->installEventFilter(new MouseWheelWidgetAdjustmentGuard(ui_.Spin1)); - ui_.Spin2->installEventFilter(new MouseWheelWidgetAdjustmentGuard(ui_.Spin2)); - - // Set appropriate labels - Vec3WidgetLabels::set(ui_.Label1, keyword_->labelType(), 0); - Vec3WidgetLabels::set(ui_.Label2, keyword_->labelType(), 1); - - refreshing_ = false; -} - -/* - * Widgets - */ - -// Spin box value changed -void RangeKeywordWidget::on_Spin1_valueChanged(double value) -{ - if (refreshing_) - return; - - if (keyword_->setMinimum(value)) - Q_EMIT(keywordDataChanged(keyword_->editSignals())); - else - { - refreshing_ = true; - ui_.Spin1->setValue(keyword_->data().minimum()); - refreshing_ = false; - } -} - -// Spin box value changed -void RangeKeywordWidget::on_Spin2_valueChanged(double value) -{ - if (refreshing_) - return; - - if (keyword_->setMaximum(value)) - Q_EMIT(keywordDataChanged(keyword_->editSignals())); - else - { - refreshing_ = true; - ui_.Spin2->setValue(keyword_->data().maximum()); - refreshing_ = false; - } -} - -/* - * Update - */ - -// Update value displayed in widget -void RangeKeywordWidget::updateValue(const Flags &mutationFlags) -{ - refreshing_ = true; - - ui_.Spin1->setValue(keyword_->data().minimum()); - ui_.Spin2->setValue(keyword_->data().maximum()); - - refreshing_ = false; -} diff --git a/src/gui/keywordWidgets/range.h b/src/gui/keywordWidgets/range.h deleted file mode 100644 index 149f612f08..0000000000 --- a/src/gui/keywordWidgets/range.h +++ /dev/null @@ -1,47 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#pragma once - -#include "gui/keywordWidgets/base.h" -#include "gui/keywordWidgets/ui_range.h" -#include "keywords/range.h" -#include - -class RangeKeywordWidget : public QWidget, public KeywordWidgetBase -{ - // All Qt declarations must include this macro - Q_OBJECT - - public: - RangeKeywordWidget(QWidget *parent, RangeKeyword *keyword, const CoreData &coreData); - - /* - * Keyword - */ - private: - // Associated keyword - RangeKeyword *keyword_; - - /* - * Widgets - */ - private: - // Main form declaration - Ui::RangeWidget ui_; - - private Q_SLOTS: - void on_Spin1_valueChanged(double value); - void on_Spin2_valueChanged(double value); - - Q_SIGNALS: - // Keyword data changed - void keywordDataChanged(int flags); - - /* - * Update - */ - public: - // Update value displayed in widget - void updateValue(const Flags &mutationFlags) override; -}; diff --git a/src/gui/keywordWidgets/range.ui b/src/gui/keywordWidgets/range.ui deleted file mode 100644 index ed2558fcf8..0000000000 --- a/src/gui/keywordWidgets/range.ui +++ /dev/null @@ -1,88 +0,0 @@ - - - RangeWidget - - - - 0 - 0 - 99 - 64 - - - - - 10 - - - - Form - - - - 0 - - - 0 - - - 0 - - - 0 - - - 4 - - - - - - - Min - - - - - - - - 0 - 0 - - - - - - - - Max - - - - - - - - 0 - 0 - - - - - - - - - - - ExponentialSpin - QDoubleSpinBox -
gui/widgets/exponentialSpin.h
-
-
- - - - -
diff --git a/src/gui/keywordWidgets/rangeVector.cpp b/src/gui/keywordWidgets/rangeVector.cpp deleted file mode 100644 index 90916451c9..0000000000 --- a/src/gui/keywordWidgets/rangeVector.cpp +++ /dev/null @@ -1,78 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#include "gui/keywordWidgets/rangeVector.h" -#include "classes/coreData.h" -#include "gui/delegates/exponentialSpin.h" -#include "gui/keywordWidgets/dropDown.h" -#include "templates/algorithms.h" -#include -#include -#include - -RangeVectorKeywordWidget::RangeVectorKeywordWidget(QWidget *parent, RangeVectorKeyword *keyword, const CoreData &coreData) - : KeywordWidgetBase(coreData), keyword_(keyword) -{ - // Create and set up the UI for our widget - ui_.setupUi(this); - - // Set up the model - ui_.RangeVectorTable->setModel(&rangeVectorModel_); - ui_.RangeVectorTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); - resetModelData(); - - // Set delegates - ui_.RangeVectorTable->setItemDelegateForColumn(1, new ExponentialSpinDelegate(this)); - - // Connect signals / slots - connect(&rangeVectorModel_, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), this, - SLOT(modelDataChanged(const QModelIndex &, const QModelIndex &))); -} - -/* - * Widgets - */ - -// List item changed -void RangeVectorKeywordWidget::modelDataChanged(const QModelIndex &, const QModelIndex &) -{ - if (refreshing_) - return; - - Q_EMIT(keywordDataChanged(keyword_->editSignals())); -} - -void RangeVectorKeywordWidget::on_RangeAddButton_clicked(bool checked) -{ - rangeVectorModel_.insertRows(rangeVectorModel_.rowCount(), 1); -} - -void RangeVectorKeywordWidget::on_RangeRemoveButton_clicked(bool checked) { rangeVectorModel_.removeRows(selectedRow(), 1); } - -/* - * Update - */ - -// Reset model data -void RangeVectorKeywordWidget::resetModelData() -{ - refreshing_ = true; - - rangeVectorModel_.setData(keyword_->data()); - - refreshing_ = false; -} - -// Update value displayed in widget -void RangeVectorKeywordWidget::updateValue(const Flags &mutationFlags) -{ - if (mutationFlags.isSet(DissolveSignals::ModulesMutated)) - resetModelData(); -} - -int RangeVectorKeywordWidget::selectedRow() const -{ - return (ui_.RangeVectorTable->selectionModel()->hasSelection() - ? ui_.RangeVectorTable->selectionModel()->currentIndex().row() - : -1); -} diff --git a/src/gui/keywordWidgets/rangeVector.h b/src/gui/keywordWidgets/rangeVector.h deleted file mode 100644 index 261e14681d..0000000000 --- a/src/gui/keywordWidgets/rangeVector.h +++ /dev/null @@ -1,59 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#pragma once - -#include "gui/keywordWidgets/base.h" -#include "gui/keywordWidgets/dropDown.h" -#include "gui/keywordWidgets/ui_rangeVector.h" -#include "gui/models/rangeVectorModel.h" -#include "keywords/rangeVector.h" -#include "math/range.h" -#include - -class RangeVectorKeywordWidget : public QWidget, public KeywordWidgetBase -{ - // All Qt declarations must include this macro - Q_OBJECT - - public: - RangeVectorKeywordWidget(QWidget *parent, RangeVectorKeyword *keyword, const CoreData &coreData); - - /* - * Keyword - */ - private: - // Associated keyword - RangeVectorKeyword *keyword_; - - /* - * Widgets - */ - private: - // Main form declaration - Ui::RangeVectorWidget ui_; - // Model for combo box - RangeVectorModel rangeVectorModel_; - - private Q_SLOTS: - void modelDataChanged(const QModelIndex &, const QModelIndex &); - void on_RangeAddButton_clicked(bool checked); - void on_RangeRemoveButton_clicked(bool checked); - - Q_SIGNALS: - // Keyword data changed - void keywordDataChanged(int flags); - - /* - * Update - */ - private: - // Reset model data - void resetModelData(); - - public: - // Update value displayed in widget - void updateValue(const Flags &mutationFlags) override; - // Returns the index of the selected row - int selectedRow() const; -}; \ No newline at end of file diff --git a/src/gui/keywordWidgets/rangeVector.ui b/src/gui/keywordWidgets/rangeVector.ui deleted file mode 100644 index 7dc80a3757..0000000000 --- a/src/gui/keywordWidgets/rangeVector.ui +++ /dev/null @@ -1,83 +0,0 @@ - - - RangeVectorWidget - - - - 0 - 0 - 320 - 162 - - - - - 10 - - - - Form - - - - 0 - - - 0 - - - 0 - - - 0 - - - 4 - - - - - - 0 - 140 - - - - - - - - 0 - - - 140 - - - - - Add - - - - :/general/icons/add.svg:/general/icons/add.svg - - - - - - - Remove - - - - :/general/icons/remove.svg:/general/icons/remove.svg - - - - - - - - - - \ No newline at end of file diff --git a/src/gui/keywordWidgets/species.cpp b/src/gui/keywordWidgets/species.cpp deleted file mode 100644 index 6404c905b2..0000000000 --- a/src/gui/keywordWidgets/species.cpp +++ /dev/null @@ -1,72 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#include "gui/keywordWidgets/species.h" -#include "classes/coreData.h" -#include "gui/helpers/mouseWheelAdjustmentGuard.h" - -SpeciesKeywordWidget::SpeciesKeywordWidget(QWidget *parent, SpeciesKeyword *keyword, const CoreData &coreData) - : QWidget(parent), KeywordWidgetBase(coreData), keyword_(keyword) -{ - // Setup our UI - ui_.setupUi(this); - - refreshing_ = true; - - // Set up the model - ui_.SpeciesCombo->setModel(&speciesModel_); - resetModelData(); - - // Set event filtering so that we do not blindly accept mouse wheel events (problematic since we will exist in a - // QScrollArea) - ui_.SpeciesCombo->installEventFilter(new MouseWheelWidgetAdjustmentGuard(ui_.SpeciesCombo)); - - refreshing_ = false; -} - -/* - * Widgets - */ - -void SpeciesKeywordWidget::on_SpeciesCombo_currentIndexChanged(int index) -{ - if (refreshing_) - return; - - // Get data from the selected item - if (index == -1) - keyword_->data() = nullptr; - else - keyword_->data() = ui_.SpeciesCombo->currentData(Qt::UserRole).value(); - - Q_EMIT(keywordDataChanged(keyword_->editSignals())); -} - -void SpeciesKeywordWidget::on_ClearButton_clicked(bool checked) -{ - if (ui_.SpeciesCombo->currentIndex() == -1 && !keyword_->data()) - return; - - ui_.SpeciesCombo->setCurrentIndex(-1); -} - -/* - * Update - */ - -// Reset model data -void SpeciesKeywordWidget::resetModelData() -{ - refreshing_ = true; - - speciesModel_.setData(coreData_.species()); - - auto it = std::find_if(coreData_.species().begin(), coreData_.species().end(), - [&](const auto &sp) { return sp.get() == keyword_->data(); }); - ui_.SpeciesCombo->setCurrentIndex(it == coreData_.species().end() ? -1 : it - coreData_.species().begin()); - - refreshing_ = false; -} - -// Update value displayed in widget -void SpeciesKeywordWidget::updateValue(const Flags &mutationFlags) {} diff --git a/src/gui/keywordWidgets/species.h b/src/gui/keywordWidgets/species.h deleted file mode 100644 index 7597171b30..0000000000 --- a/src/gui/keywordWidgets/species.h +++ /dev/null @@ -1,54 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#pragma once - -#include "gui/keywordWidgets/base.h" -#include "gui/keywordWidgets/ui_species.h" -#include "gui/models/speciesModel.h" -#include "keywords/species.h" -#include - -class SpeciesKeywordWidget : public QWidget, public KeywordWidgetBase -{ - // All Qt declarations must include this macro - Q_OBJECT - - public: - SpeciesKeywordWidget(QWidget *parent, SpeciesKeyword *keyword, const CoreData &coreData); - - /* - * Keyword - */ - private: - // Associated keyword - SpeciesKeyword *keyword_; - - /* - * Widgets - */ - private: - // Main form declaration - Ui::SpeciesKeywordWidget ui_; - // Model for combo box - SpeciesModel speciesModel_; - - private Q_SLOTS: - void on_SpeciesCombo_currentIndexChanged(int index); - void on_ClearButton_clicked(bool checked); - - Q_SIGNALS: - // Keyword data changed - void keywordDataChanged(int flags); - - /* - * Update - */ - private: - // Reset model data - void resetModelData(); - - public: - // Update value displayed in widget - void updateValue(const Flags &mutationFlags) override; -}; diff --git a/src/gui/keywordWidgets/species.ui b/src/gui/keywordWidgets/species.ui deleted file mode 100644 index 9047318a06..0000000000 --- a/src/gui/keywordWidgets/species.ui +++ /dev/null @@ -1,79 +0,0 @@ - - - SpeciesKeywordWidget - - - - 0 - 0 - 207 - 29 - - - - - 0 - 0 - - - - - 10 - - - - Form - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - - - - - Clear selected - - - ... - - - - :/general/icons/clear.svg:/general/icons/clear.svg - - - - 16 - 16 - - - - - - - - - - - diff --git a/src/gui/keywordWidgets/speciesSite.cpp b/src/gui/keywordWidgets/speciesSite.cpp deleted file mode 100644 index b4fda56d5f..0000000000 --- a/src/gui/keywordWidgets/speciesSite.cpp +++ /dev/null @@ -1,142 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#include "classes/speciesSite.h" -#include "classes/coreData.h" -#include "classes/species.h" -#include "gui/keywordWidgets/speciesSite.h" -#include "templates/variantPointer.h" -#include -#include -#include -#include -#include - -SpeciesSiteKeywordWidget::SpeciesSiteKeywordWidget(QWidget *parent, SpeciesSiteKeyword *keyword, const CoreData &coreData) - : KeywordDropDown(this), KeywordWidgetBase(coreData), keyword_(keyword) -{ - // Create and set up the UI for our widget in the drop-down's widget container - ui_.setupUi(dropWidget()); - - // Connect signals / slots - connect(ui_.ClearButton, SIGNAL(clicked(bool)), this, SLOT(clearDataButton_clicked(bool))); - connect(ui_.SpeciesCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(updateAvailableSites(int))); - connect(ui_.SiteCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(siteCombo_currentIndexChanged(int))); - - ui_.SpeciesCombo->setModel(&speciesModel_); - siteFilterProxy_.setSourceModel(&siteModel_); - ui_.SiteCombo->setModel(&siteFilterProxy_); - - // Set current information - resetWidgets(); -} - -/* - * Widgets - */ - -void SpeciesSiteKeywordWidget::clearDataButton_clicked(bool checked) -{ - if (refreshing_) - return; - - keyword_->data() = nullptr; - - resetWidgets(); - - updateSummaryText(); - - Q_EMIT(keywordDataChanged(keyword_->editSignals())); -} - -void SpeciesSiteKeywordWidget::siteCombo_currentIndexChanged(int index) -{ - if (refreshing_) - return; - - // Get the current site, which might be filtered via our proxy. - auto filteredModelIndex = siteFilterProxy_.index(index, 0); - if (filteredModelIndex.isValid()) - { - auto siteIndex = siteFilterProxy_.mapToSource(filteredModelIndex); - auto *site = siteModel_.data(siteIndex, Qt::UserRole).value(); - if (site) - { - keyword_->data() = site; - - updateSummaryText(); - - Q_EMIT(keywordDataChanged(keyword_->editSignals())); - } - } -} - -/* - * Update - */ - -// Update value displayed in widget -void SpeciesSiteKeywordWidget::updateValue(const Flags &mutationFlags) -{ - if (mutationFlags.isSet(DissolveSignals::SpeciesMutated) || mutationFlags.isSet(DissolveSignals::SpeciesSiteMutated)) - resetWidgets(); -} - -void SpeciesSiteKeywordWidget::updateAvailableSpecies() -{ - refreshing_ = true; - - speciesModel_.setData(coreData_.species()); - if (keyword_->data()) - ui_.SpeciesCombo->setCurrentIndex(std::find_if(coreData_.species().begin(), coreData_.species().end(), - [&](const auto &sp) { return sp.get() == keyword_->data()->parent(); }) - - coreData_.species().begin()); - else - ui_.SpeciesCombo->setCurrentIndex(-1); - - refreshing_ = false; -} - -void SpeciesSiteKeywordWidget::updateAvailableSites(int speciesIndex) -{ - refreshing_ = true; - - if (speciesIndex == -1) - siteModel_.setData(std::nullopt); - else - { - auto &sites = coreData_.species()[speciesIndex]->sites(); - siteModel_.setData(sites); - if (keyword_->axesRequired()) - siteFilterProxy_.setFlag(SpeciesSiteFilterProxy::IsOriented); - else - siteFilterProxy_.removeFlag(SpeciesSiteFilterProxy::IsOriented); - if (keyword_->data()) - ui_.SiteCombo->setCurrentIndex( - std::find_if(sites.begin(), sites.end(), [&](const auto &site) { return site.get() == keyword_->data(); }) - - sites.begin()); - else - ui_.SiteCombo->setCurrentIndex(-1); - } - - refreshing_ = false; -} - -// Reset widgets -void SpeciesSiteKeywordWidget::resetWidgets() -{ - updateAvailableSpecies(); - updateAvailableSites(ui_.SpeciesCombo->currentIndex()); - - updateSummaryText(); -} - -// Update summary text -void SpeciesSiteKeywordWidget::updateSummaryText() -{ - if (keyword_->data()) - setSummaryText( - QString::fromStdString(std::format("{} ({})", keyword_->data()->name(), keyword_->data()->parent()->name()))); - else - setSummaryText(""); -} diff --git a/src/gui/keywordWidgets/speciesSite.h b/src/gui/keywordWidgets/speciesSite.h deleted file mode 100644 index eb36fb1645..0000000000 --- a/src/gui/keywordWidgets/speciesSite.h +++ /dev/null @@ -1,70 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#pragma once - -#include "gui/keywordWidgets/base.h" -#include "gui/keywordWidgets/dropDown.h" -#include "gui/keywordWidgets/ui_speciesSite.h" -#include "gui/models/speciesModel.h" -#include "gui/models/speciesSiteFilterProxy.h" -#include "gui/models/speciesSiteModel.h" -#include "keywords/speciesSite.h" -#include - -// Forward Declarations -class Species; - -class SpeciesSiteKeywordWidget : public KeywordDropDown, public KeywordWidgetBase -{ - // All Qt declarations must include this macro - Q_OBJECT - - public: - SpeciesSiteKeywordWidget(QWidget *parent, SpeciesSiteKeyword *keyword, const CoreData &coreData); - - /* - * Keyword - */ - private: - // Associated keyword - SpeciesSiteKeyword *keyword_; - - /* - * Widgets - */ - private: - // Main form declaration - Ui::SpeciesSiteWidget ui_; - // Model for species - SpeciesModel speciesModel_; - // Sites model and filter proxy - SpeciesSiteModel siteModel_; - SpeciesSiteFilterProxy siteFilterProxy_; - - private Q_SLOTS: - void clearDataButton_clicked(bool checked); - void siteCombo_currentIndexChanged(int index); - - Q_SIGNALS: - // Keyword data changed - void keywordDataChanged(int flags); - - /* - * Update - */ - private Q_SLOTS: - // Update combo boxes - void updateAvailableSpecies(); - void updateAvailableSites(int speciesIndex = -1); - - private: - // Reset widgets - void resetWidgets(); - - public: - // Update value displayed in widget - void updateValue(const Flags &mutationFlags) override; - // Update summary text - void updateSummaryText(); -}; diff --git a/src/gui/keywordWidgets/speciesSite.ui b/src/gui/keywordWidgets/speciesSite.ui deleted file mode 100644 index 58c6af465f..0000000000 --- a/src/gui/keywordWidgets/speciesSite.ui +++ /dev/null @@ -1,172 +0,0 @@ - - - SpeciesSiteWidget - - - - 0 - 0 - 218 - 62 - - - - - 0 - 0 - - - - - 10 - - - - Form - - - - 4 - - - 4 - - - 4 - - - 4 - - - 4 - - - - - 4 - - - - - - 0 - 0 - - - - - 16 - 16 - - - - - - - :/general/icons/species.svg - - - true - - - - - - - - 0 - 0 - - - - Species - - - - - - - Clear selected - - - ... - - - - :/general/icons/clear.svg:/general/icons/clear.svg - - - - 16 - 16 - - - - - - - - - 0 - 0 - - - - - - - - - 0 - 0 - - - - - 16 - 16 - - - - - - - :/general/icons/site.svg - - - true - - - - - - - - 0 - 0 - - - - Site - - - - - - - - 0 - 0 - - - - - - - - - - - - - diff --git a/src/gui/keywordWidgets/speciesSiteVector.cpp b/src/gui/keywordWidgets/speciesSiteVector.cpp deleted file mode 100644 index 622cb3c9ce..0000000000 --- a/src/gui/keywordWidgets/speciesSiteVector.cpp +++ /dev/null @@ -1,77 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#include "gui/keywordWidgets/speciesSiteVector.h" -#include "classes/coreData.h" -#include "classes/species.h" -#include "classes/speciesSite.h" -#include "templates/algorithms.h" - -SpeciesSiteVectorKeywordWidget::SpeciesSiteVectorKeywordWidget(QWidget *parent, SpeciesSiteVectorKeyword *keyword, - const CoreData &coreData) - : KeywordDropDown(this), KeywordWidgetBase(coreData), keyword_(keyword) -{ - // Create and set up the UI for our widget in the drop-down's widget container - ui_.setupUi(dropWidget()); - - // Set up the model - sitesFilterProxy_.setSourceModel(&sites_); - if (keyword->axesRequired()) - sitesFilterProxy_.setFlag(SitesFilterProxy::HasAxes); - ui_.SitesTree->setModel(&sitesFilterProxy_); - sites_.setCheckStateData(keyword_->data()); - resetModelData(); - - // Connect signals / slots - connect(&sites_, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &, const QVector &)), this, - SLOT(modelDataChanged(const QModelIndex &, const QModelIndex &))); -} - -/* - * Widgets - */ - -void SpeciesSiteVectorKeywordWidget::modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight) -{ - if (refreshing_) - return; - - updateSummaryText(); - - Q_EMIT(keywordDataChanged(keyword_->editSignals())); -} - -/* - * Update - */ - -// Reset model data -void SpeciesSiteVectorKeywordWidget::resetModelData() -{ - refreshing_ = true; - - sites_.setData(coreData_.species()); - ui_.SitesTree->expandAll(); - updateSummaryText(); - - refreshing_ = false; -} - -// Update value displayed in widget -void SpeciesSiteVectorKeywordWidget::updateValue(const Flags &mutationFlags) -{ - if (mutationFlags.isSet(DissolveSignals::SpeciesMutated) || mutationFlags.isSet(DissolveSignals::SpeciesSiteMutated)) - resetModelData(); -} - -// Update summary text -void SpeciesSiteVectorKeywordWidget::updateSummaryText() -{ - QString siteText; - if (keyword_->data().empty()) - setSummaryText(""); - else - setSummaryText( - QString::fromStdString(joinStrings(keyword_->data(), ", ", [](const auto &site) - { return std::format("{} ({})", site->name(), site->parent()->name()); }))); -} diff --git a/src/gui/keywordWidgets/speciesSiteVector.h b/src/gui/keywordWidgets/speciesSiteVector.h deleted file mode 100644 index 9f1b2a60c8..0000000000 --- a/src/gui/keywordWidgets/speciesSiteVector.h +++ /dev/null @@ -1,63 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#pragma once - -#include "gui/keywordWidgets/base.h" -#include "gui/keywordWidgets/dropDown.h" -#include "gui/keywordWidgets/ui_speciesSiteVector.h" -#include "gui/models/sitesFilterProxy.h" -#include "gui/models/sitesModel.h" -#include "keywords/speciesSiteVector.h" -#include - -// Forward Declarations -class Species; - -class SpeciesSiteVectorKeywordWidget : public KeywordDropDown, public KeywordWidgetBase -{ - // All Qt declarations must include this macro - Q_OBJECT - - public: - SpeciesSiteVectorKeywordWidget(QWidget *parent, SpeciesSiteVectorKeyword *keyword, const CoreData &coreData); - ~SpeciesSiteVectorKeywordWidget() override = default; - - /* - * Keyword - */ - private: - // Associated keyword - SpeciesSiteVectorKeyword *keyword_; - - /* - * Widgets - */ - private: - // Main form declaration - Ui::SpeciesSiteVectorWidget ui_; - // Site models for Species - SitesModel sites_; - // Proxy filters for sites - SitesFilterProxy sitesFilterProxy_; - - private Q_SLOTS: - void modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight); - - Q_SIGNALS: - // Keyword data changed - void keywordDataChanged(int flags); - - /* - * Update - */ - private: - // Reset model data - void resetModelData(); - - public: - // Update value displayed in widget - void updateValue(const Flags &mutationFlags) override; - // Update summary text - void updateSummaryText(); -}; diff --git a/src/gui/keywordWidgets/speciesSiteVector.ui b/src/gui/keywordWidgets/speciesSiteVector.ui deleted file mode 100644 index cdfe6d0b4d..0000000000 --- a/src/gui/keywordWidgets/speciesSiteVector.ui +++ /dev/null @@ -1,52 +0,0 @@ - - - SpeciesSiteVectorWidget - - - - 0 - 0 - 264 - 200 - - - - - 0 - 0 - - - - - 10 - - - - Form - - - - 4 - - - 4 - - - 4 - - - 4 - - - 4 - - - - - - - - - - - diff --git a/src/gui/keywordWidgets/speciesVector.cpp b/src/gui/keywordWidgets/speciesVector.cpp deleted file mode 100644 index 2459292fec..0000000000 --- a/src/gui/keywordWidgets/speciesVector.cpp +++ /dev/null @@ -1,72 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#include "gui/keywordWidgets/speciesVector.h" -#include "classes/coreData.h" -#include "classes/species.h" -#include "templates/algorithms.h" -#include -#include -#include - -SpeciesVectorKeywordWidget::SpeciesVectorKeywordWidget(QWidget *parent, SpeciesVectorKeyword *keyword, const CoreData &coreData) - : KeywordDropDown(this), KeywordWidgetBase(coreData), keyword_(keyword) -{ - // Create and set up the UI for our widget in the drop-down's widget container - ui_.setupUi(dropWidget()); - - // Set up the model - ui_.SpeciesList->setModel(&speciesModel_); - speciesModel_.setCheckStateData(keyword_->data()); - resetModelData(); - - // Connect signals / slots - connect(&speciesModel_, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), this, - SLOT(modelDataChanged(const QModelIndex &, const QModelIndex &))); -} - -/* - * Widgets - */ - -void SpeciesVectorKeywordWidget::modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight) -{ - if (refreshing_) - return; - - updateSummaryText(); - - Q_EMIT(keywordDataChanged(keyword_->editSignals())); -} - -/* - * Update - */ - -// Reset model data -void SpeciesVectorKeywordWidget::resetModelData() -{ - refreshing_ = true; - - speciesModel_.setData(coreData_.species()); - - updateSummaryText(); - - refreshing_ = false; -} - -// Update value displayed in widget -void SpeciesVectorKeywordWidget::updateValue(const Flags &mutationFlags) -{ - if (mutationFlags.isSet(DissolveSignals::SpeciesMutated)) - resetModelData(); -} - -// Update summary text -void SpeciesVectorKeywordWidget::updateSummaryText() -{ - if (keyword_->data().empty()) - setSummaryText(""); - else - setSummaryText(QString::fromStdString(joinStrings(keyword_->data(), ", ", [](const auto &sp) { return sp->name(); }))); -} diff --git a/src/gui/keywordWidgets/speciesVector.h b/src/gui/keywordWidgets/speciesVector.h deleted file mode 100644 index 13d4c40fe5..0000000000 --- a/src/gui/keywordWidgets/speciesVector.h +++ /dev/null @@ -1,59 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#pragma once - -#include "gui/keywordWidgets/base.h" -#include "gui/keywordWidgets/dropDown.h" -#include "gui/keywordWidgets/ui_speciesVector.h" -#include "gui/models/speciesModel.h" -#include "keywords/speciesVector.h" -#include - -// Forward Declarations -class Species; - -class SpeciesVectorKeywordWidget : public KeywordDropDown, public KeywordWidgetBase -{ - // All Qt declarations must include this macro - Q_OBJECT - - public: - SpeciesVectorKeywordWidget(QWidget *parent, SpeciesVectorKeyword *keyword, const CoreData &coreData); - - /* - * Keyword - */ - private: - // Associated keyword - SpeciesVectorKeyword *keyword_; - - /* - * Widgets - */ - private: - // Main form declaration - Ui::SpeciesVectorWidget ui_; - // Model for the Species list - SpeciesModel speciesModel_; - - private Q_SLOTS: - void modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight); - - Q_SIGNALS: - // Keyword data changed - void keywordDataChanged(int flags); - - /* - * Update - */ - private: - // Reset model data - void resetModelData(); - - public: - // Update value displayed in widget - void updateValue(const Flags &mutationFlags) override; - // Update summary text - void updateSummaryText(); -}; diff --git a/src/gui/keywordWidgets/speciesVector.ui b/src/gui/keywordWidgets/speciesVector.ui deleted file mode 100644 index a281328460..0000000000 --- a/src/gui/keywordWidgets/speciesVector.ui +++ /dev/null @@ -1,44 +0,0 @@ - - - SpeciesVectorWidget - - - - 0 - 0 - 144 - 85 - - - - - 10 - - - - Form - - - - 0 - - - 0 - - - 0 - - - 0 - - - 4 - - - - - - - - - diff --git a/src/gui/keywordWidgets/stdString.cpp b/src/gui/keywordWidgets/stdString.cpp deleted file mode 100644 index 191f9dfab6..0000000000 --- a/src/gui/keywordWidgets/stdString.cpp +++ /dev/null @@ -1,42 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#include "gui/keywordWidgets/stdString.h" - -StringKeywordWidget::StringKeywordWidget(QWidget *parent, StringKeyword *keyword, const CoreData &coreData) - : QLineEdit(parent), KeywordWidgetBase(coreData), keyword_(keyword) -{ - setText(QString::fromStdString(keyword_->data())); - - // Connect the currentTextChanged signal to our own slot - connect(this, SIGNAL(textChanged(QString)), this, SLOT(lineEditTextChanged(QString))); -} - -/* - * Signals / Slots - */ - -// Line edit text changed -void StringKeywordWidget::lineEditTextChanged(const QString &text) -{ - if (refreshing_) - return; - - keyword_->data() = qPrintable(text); - - Q_EMIT(keywordDataChanged(keyword_->editSignals())); -} - -/* - * Update - */ - -// Update value displayed in widget -void StringKeywordWidget::updateValue(const Flags &mutationFlags) -{ - refreshing_ = true; - - setText(QString::fromStdString(keyword_->data())); - - refreshing_ = false; -} diff --git a/src/gui/keywordWidgets/stdString.h b/src/gui/keywordWidgets/stdString.h deleted file mode 100644 index 9262f008ea..0000000000 --- a/src/gui/keywordWidgets/stdString.h +++ /dev/null @@ -1,42 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#pragma once - -#include "gui/keywordWidgets/base.h" -#include "keywords/stdString.h" -#include - -class StringKeywordWidget : public QLineEdit, public KeywordWidgetBase -{ - // All Qt declarations must include this macro - Q_OBJECT - - public: - StringKeywordWidget(QWidget *parent, StringKeyword *keyword, const CoreData &coreData); - - /* - * Keyword - */ - private: - // Associated keyword - StringKeyword *keyword_; - - /* - * Signals / Slots - */ - private Q_SLOTS: - // Line edit text changed - void lineEditTextChanged(const QString &text); - - Q_SIGNALS: - // Keyword data changed - void keywordDataChanged(int flags); - - /* - * Update - */ - public: - // Update value displayed in widget - void updateValue(const Flags &mutationFlags) override; -}; diff --git a/src/gui/keywordWidgets/vec3Double.cpp b/src/gui/keywordWidgets/vec3Double.cpp deleted file mode 100644 index 7206c271e1..0000000000 --- a/src/gui/keywordWidgets/vec3Double.cpp +++ /dev/null @@ -1,108 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#include "gui/keywordWidgets/vec3Double.h" -#include "gui/helpers/mouseWheelAdjustmentGuard.h" -#include "gui/keywordWidgets/vec3Labels.h" - -Vec3DoubleKeywordWidget::Vec3DoubleKeywordWidget(QWidget *parent, Vec3DoubleKeyword *keyword, const CoreData &coreData) - : QWidget(parent), KeywordWidgetBase(coreData), keyword_(keyword) -{ - // Setup our UI - ui_.setupUi(this); - - refreshing_ = true; - - // Set minimum and maximum values for each component - if (keyword_->minimumLimit()) - { - ui_.Spin1->setMinimum(keyword_->minimumLimit().value().x); - ui_.Spin2->setMinimum(keyword_->minimumLimit().value().y); - ui_.Spin3->setMinimum(keyword_->minimumLimit().value().z); - } - if (keyword_->maximumLimit()) - { - ui_.Spin1->setMaximum(keyword_->maximumLimit().value().x); - ui_.Spin2->setMaximum(keyword_->maximumLimit().value().y); - ui_.Spin3->setMaximum(keyword_->maximumLimit().value().z); - } - - // Set current values - ui_.Spin1->setValue(keyword_->data().x); - ui_.Spin2->setValue(keyword_->data().y); - ui_.Spin3->setValue(keyword_->data().z); - - // Set event filtering so that we do not blindly accept mouse wheel events (problematic since we will exist in a - // QScrollArea) - ui_.Spin1->installEventFilter(new MouseWheelWidgetAdjustmentGuard(ui_.Spin1)); - ui_.Spin2->installEventFilter(new MouseWheelWidgetAdjustmentGuard(ui_.Spin2)); - ui_.Spin3->installEventFilter(new MouseWheelWidgetAdjustmentGuard(ui_.Spin3)); - - // Set appropriate labels - Vec3WidgetLabels::set(ui_.Label1, keyword_->labelType(), 0); - Vec3WidgetLabels::set(ui_.Label2, keyword_->labelType(), 1); - Vec3WidgetLabels::set(ui_.Label3, keyword_->labelType(), 2); - - refreshing_ = false; -} - -/* - * Widgets - */ - -// Spin box value changed -void Vec3DoubleKeywordWidget::on_Spin1_valueChanged(double value) -{ - if (refreshing_) - return; - - auto newVec = keyword_->data(); - newVec.x = value; - keyword_->setData(newVec); - - Q_EMIT(keywordDataChanged(keyword_->editSignals())); -} - -// Spin box value changed -void Vec3DoubleKeywordWidget::on_Spin2_valueChanged(double value) -{ - if (refreshing_) - return; - - auto newVec = keyword_->data(); - newVec.y = value; - keyword_->setData(newVec); - - Q_EMIT(keywordDataChanged(keyword_->editSignals())); -} - -// Spin box value changed -void Vec3DoubleKeywordWidget::on_Spin3_valueChanged(double value) -{ - if (refreshing_) - return; - - auto newVec = keyword_->data(); - newVec.z = value; - keyword_->setData(newVec); - - Q_EMIT(keywordDataChanged(keyword_->editSignals())); -} - -/* - * Update - */ - -// Update value displayed in widget -void Vec3DoubleKeywordWidget::updateValue(const Flags &mutationFlags) -{ - refreshing_ = true; - - const auto v = keyword_->data(); - - ui_.Spin1->setValue(v.x); - ui_.Spin2->setValue(v.y); - ui_.Spin3->setValue(v.z); - - refreshing_ = false; -} diff --git a/src/gui/keywordWidgets/vec3Double.h b/src/gui/keywordWidgets/vec3Double.h deleted file mode 100644 index 78e5c70e47..0000000000 --- a/src/gui/keywordWidgets/vec3Double.h +++ /dev/null @@ -1,48 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#pragma once - -#include "gui/keywordWidgets/base.h" -#include "gui/keywordWidgets/ui_vec3Double.h" -#include "keywords/vec3Double.h" -#include - -class Vec3DoubleKeywordWidget : public QWidget, public KeywordWidgetBase -{ - // All Qt declarations must include this macro - Q_OBJECT - - public: - Vec3DoubleKeywordWidget(QWidget *parent, Vec3DoubleKeyword *keyword, const CoreData &coreData); - - /* - * Keyword - */ - private: - // Associated keyword - Vec3DoubleKeyword *keyword_; - - /* - * Widgets - */ - private: - // Main form declaration - Ui::Vec3DoubleWidget ui_; - - private Q_SLOTS: - void on_Spin1_valueChanged(double value); - void on_Spin2_valueChanged(double value); - void on_Spin3_valueChanged(double value); - - Q_SIGNALS: - // Keyword data changed - void keywordDataChanged(int flags); - - /* - * Update - */ - public: - // Update value displayed in widget - void updateValue(const Flags &mutationFlags) override; -}; diff --git a/src/gui/keywordWidgets/vec3Double.ui b/src/gui/keywordWidgets/vec3Double.ui deleted file mode 100644 index d225e3bf22..0000000000 --- a/src/gui/keywordWidgets/vec3Double.ui +++ /dev/null @@ -1,105 +0,0 @@ - - - Vec3DoubleWidget - - - - 0 - 0 - 106 - 98 - - - - - 10 - - - - Form - - - - 0 - - - 0 - - - 0 - - - 0 - - - 4 - - - - - - - Min - - - - - - - Max - - - - - - - Delta - - - - - - - - 0 - 0 - - - - - - - - - 0 - 0 - - - - - - - - - 0 - 0 - - - - - - - - - - - ExponentialSpin - QDoubleSpinBox -
gui/widgets/exponentialSpin.h
-
-
- - - - -
diff --git a/src/gui/keywordWidgets/vec3Integer.cpp b/src/gui/keywordWidgets/vec3Integer.cpp deleted file mode 100644 index 0d750b5cb1..0000000000 --- a/src/gui/keywordWidgets/vec3Integer.cpp +++ /dev/null @@ -1,101 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#include "gui/keywordWidgets/vec3Integer.h" -#include "gui/helpers/mouseWheelAdjustmentGuard.h" -#include "gui/keywordWidgets/vec3Labels.h" - -Vec3IntegerKeywordWidget::Vec3IntegerKeywordWidget(QWidget *parent, Vec3IntegerKeyword *keyword, const CoreData &coreData) - : QWidget(parent), KeywordWidgetBase(coreData), keyword_(keyword) -{ - // Setup our UI - ui_.setupUi(this); - - refreshing_ = true; - - // Set minimum and maximum values for each component - ui_.Spin1->setRange(keyword_->minimumLimit() ? keyword_->minimumLimit().value().x : -1e6, - keyword_->maximumLimit() ? keyword_->maximumLimit().value().x : 1e6); - ui_.Spin2->setRange(keyword_->minimumLimit() ? keyword_->minimumLimit().value().y : -1e6, - keyword_->maximumLimit() ? keyword_->maximumLimit().value().y : 1e6); - ui_.Spin3->setRange(keyword_->minimumLimit() ? keyword_->minimumLimit().value().z : -1e6, - keyword_->maximumLimit() ? keyword_->maximumLimit().value().z : 1e6); - - // Set current values - ui_.Spin1->setValue(keyword_->data().x); - ui_.Spin2->setValue(keyword_->data().y); - ui_.Spin3->setValue(keyword_->data().z); - - // Set event filtering so that we do not blindly accept mouse wheel events (problematic since we will exist in a - // QScrollArea) - ui_.Spin1->installEventFilter(new MouseWheelWidgetAdjustmentGuard(ui_.Spin1)); - ui_.Spin2->installEventFilter(new MouseWheelWidgetAdjustmentGuard(ui_.Spin2)); - ui_.Spin3->installEventFilter(new MouseWheelWidgetAdjustmentGuard(ui_.Spin3)); - - // Set appropriate labels - Vec3WidgetLabels::set(ui_.Label1, keyword_->labelType(), 0); - Vec3WidgetLabels::set(ui_.Label2, keyword_->labelType(), 1); - Vec3WidgetLabels::set(ui_.Label3, keyword_->labelType(), 2); - - refreshing_ = false; -} - -/* - * Widgets - */ - -// Spin box value changed -void Vec3IntegerKeywordWidget::on_Spin1_valueChanged(int value) -{ - if (refreshing_) - return; - - auto newVec = keyword_->data(); - newVec.x = value; - keyword_->setData(newVec); - - Q_EMIT(keywordDataChanged(keyword_->editSignals())); -} - -// Spin box value changed -void Vec3IntegerKeywordWidget::on_Spin2_valueChanged(int value) -{ - if (refreshing_) - return; - - auto newVec = keyword_->data(); - newVec.y = value; - keyword_->setData(newVec); - - Q_EMIT(keywordDataChanged(keyword_->editSignals())); -} - -// Spin box value changed -void Vec3IntegerKeywordWidget::on_Spin3_valueChanged(int value) -{ - if (refreshing_) - return; - - auto newVec = keyword_->data(); - newVec.z = value; - keyword_->setData(newVec); - - Q_EMIT(keywordDataChanged(keyword_->editSignals())); -} -/* - * Update - */ - -// Update value displayed in widget -void Vec3IntegerKeywordWidget::updateValue(const Flags &mutationFlags) -{ - refreshing_ = true; - - Vector3i v = keyword_->data(); - - ui_.Spin1->setValue(v.x); - ui_.Spin2->setValue(v.y); - ui_.Spin3->setValue(v.z); - - refreshing_ = false; -} diff --git a/src/gui/keywordWidgets/vec3Integer.h b/src/gui/keywordWidgets/vec3Integer.h deleted file mode 100644 index 0bbdb115a4..0000000000 --- a/src/gui/keywordWidgets/vec3Integer.h +++ /dev/null @@ -1,49 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#pragma once - -#include "gui/keywordWidgets/base.h" -#include "gui/keywordWidgets/ui_vec3Integer.h" -#include "keywords/vec3Integer.h" -#include - -class Vec3IntegerKeywordWidget : public QWidget, public KeywordWidgetBase -{ - // All Qt declarations must include this macro - Q_OBJECT - - public: - Vec3IntegerKeywordWidget(QWidget *parent, Vec3IntegerKeyword *keyword, const CoreData &coreData); - - /* - * Keyword - */ - private: - // Associated keyword - Vec3IntegerKeyword *keyword_; - - /* - * Widgets - */ - private: - // Main form declaration - Ui::Vec3IntegerWidget ui_; - - private Q_SLOTS: - // Spin box value changed - void on_Spin1_valueChanged(int value); - void on_Spin2_valueChanged(int value); - void on_Spin3_valueChanged(int value); - - Q_SIGNALS: - // Keyword data changed - void keywordDataChanged(int flags); - - /* - * Update - */ - public: - // Update value displayed in widget - void updateValue(const Flags &mutationFlags) override; -}; diff --git a/src/gui/keywordWidgets/vec3Integer.ui b/src/gui/keywordWidgets/vec3Integer.ui deleted file mode 100644 index 2996988117..0000000000 --- a/src/gui/keywordWidgets/vec3Integer.ui +++ /dev/null @@ -1,77 +0,0 @@ - - - Vec3IntegerWidget - - - - 0 - 0 - 94 - 98 - - - - - 10 - - - - Form - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - Min - - - - - - - - - - Max - - - - - - - - - - Delta - - - - - - - - - - - - - - - diff --git a/src/gui/keywordWidgets/vec3Labels.cpp b/src/gui/keywordWidgets/vec3Labels.cpp deleted file mode 100644 index 0333bb0f1d..0000000000 --- a/src/gui/keywordWidgets/vec3Labels.cpp +++ /dev/null @@ -1,67 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#include "gui/keywordWidgets/vec3Labels.h" - -// Set/hide/show label according to labelling type -void Vec3WidgetLabels::set(QLabel *label, Vec3Labels::LabelType labelType, int index) -{ - // Show / hide label - label->setVisible(labelType != Vec3Labels::NoLabels); - - // Set label - switch (labelType) - { - case (Vec3Labels::NoLabels): - label->setText(""); - break; - case (Vec3Labels::ABCLabels): - if (index == 0) - label->setText("A"); - else if (index == 1) - label->setText("B"); - else if (index == 2) - label->setText("C"); - break; - case (Vec3Labels::AlphaBetaGammaLabels): - if (index == 0) - label->setText(QString::fromUtf8("\u03b1")); - else if (index == 1) - label->setText(QString::fromUtf8("\u03b2")); - else if (index == 2) - label->setText(QString::fromUtf8("\u03b3")); - break; - case (Vec3Labels::MinMaxDeltaLabels): - if (index == 0) - label->setText("Min"); - else if (index == 1) - label->setText("Max"); - else if (index == 2) - label->setText("Delta"); - break; - case (Vec3Labels::MinMaxBinwidthlabels): - if (index == 0) - label->setText("Min"); - else if (index == 1) - label->setText("Max"); - else if (index == 2) - label->setText("Bin Width"); - break; - case (Vec3Labels::HKLLabels): - if (index == 0) - label->setText("H"); - else if (index == 1) - label->setText("K"); - else if (index == 2) - label->setText("L"); - break; - case (Vec3Labels::XYZLabels): - if (index == 0) - label->setText("X"); - else if (index == 1) - label->setText("Y"); - else if (index == 2) - label->setText("Z"); - break; - } -} diff --git a/src/gui/keywordWidgets/vec3Labels.h b/src/gui/keywordWidgets/vec3Labels.h deleted file mode 100644 index afd72826c1..0000000000 --- a/src/gui/keywordWidgets/vec3Labels.h +++ /dev/null @@ -1,15 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#pragma once - -#include "keywords/vec3Labels.h" -#include - -// Vec3 Widget Labels -class Vec3WidgetLabels -{ - public: - // Set/hide/show label according to labelling type - static void set(QLabel *label, Vec3Labels::LabelType labelType, int index); -}; diff --git a/src/gui/keywordWidgets/vec3NodeValue.cpp b/src/gui/keywordWidgets/vec3NodeValue.cpp deleted file mode 100644 index 6df702b191..0000000000 --- a/src/gui/keywordWidgets/vec3NodeValue.cpp +++ /dev/null @@ -1,119 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#include "gui/keywordWidgets/vec3NodeValue.h" -#include "gui/keywordWidgets/vec3Labels.h" - -Vec3NodeValueKeywordWidget::Vec3NodeValueKeywordWidget(QWidget *parent, Vec3NodeValueKeyword *keyword, const CoreData &coreData) - : QWidget(parent), KeywordWidgetBase(coreData), keyword_(keyword) -{ - // Setup our UI - ui_.setupUi(this); - - refreshing_ = true; - - // Set appropriate labels - Vec3WidgetLabels::set(ui_.ValueALabel, keyword_->labelType(), 0); - Vec3WidgetLabels::set(ui_.ValueBLabel, keyword_->labelType(), 1); - Vec3WidgetLabels::set(ui_.ValueCLabel, keyword_->labelType(), 2); - - // Set expression texts - ui_.ValueAEdit->setText(QString::fromStdString(keyword_->data().x.asString())); - ui_.ValueBEdit->setText(QString::fromStdString(keyword_->data().y.asString())); - ui_.ValueCEdit->setText(QString::fromStdString(keyword_->data().z.asString())); - - ui_.ValueAValidIndicator->setOK(keyword_->data().x.isValid()); - ui_.ValueBValidIndicator->setOK(keyword_->data().y.isValid()); - ui_.ValueCValidIndicator->setOK(keyword_->data().z.isValid()); - - refreshing_ = false; -} - -/* - * Widgets - */ - -void Vec3NodeValueKeywordWidget::on_ValueAEdit_editingFinished() -{ - if (refreshing_) - return; - - keyword_->setData(0, qPrintable(ui_.ValueAEdit->text())); - ui_.ValueAValidIndicator->setOK(keyword_->data().x.isValid()); - - Q_EMIT(keywordDataChanged(keyword_->editSignals())); -} - -void Vec3NodeValueKeywordWidget::on_ValueAEdit_returnPressed() -{ - if (refreshing_) - return; - - keyword_->setData(0, qPrintable(ui_.ValueAEdit->text())); - ui_.ValueAValidIndicator->setOK(keyword_->data().x.isValid()); - - Q_EMIT(keywordDataChanged(keyword_->editSignals())); -} - -void Vec3NodeValueKeywordWidget::on_ValueBEdit_editingFinished() -{ - if (refreshing_) - return; - - keyword_->setData(1, qPrintable(ui_.ValueBEdit->text())); - ui_.ValueBValidIndicator->setOK(keyword_->data().y.isValid()); - - Q_EMIT(keywordDataChanged(keyword_->editSignals())); -} - -void Vec3NodeValueKeywordWidget::on_ValueBEdit_returnPressed() -{ - if (refreshing_) - return; - - keyword_->setData(1, qPrintable(ui_.ValueBEdit->text())); - ui_.ValueBValidIndicator->setOK(keyword_->data().y.isValid()); - - Q_EMIT(keywordDataChanged(keyword_->editSignals())); -} - -void Vec3NodeValueKeywordWidget::on_ValueCEdit_editingFinished() -{ - if (refreshing_) - return; - - keyword_->setData(2, qPrintable(ui_.ValueCEdit->text())); - ui_.ValueCValidIndicator->setOK(keyword_->data().z.isValid()); - - Q_EMIT(keywordDataChanged(keyword_->editSignals())); -} - -void Vec3NodeValueKeywordWidget::on_ValueCEdit_returnPressed() -{ - if (refreshing_) - return; - - keyword_->setData(2, qPrintable(ui_.ValueCEdit->text())); - ui_.ValueCValidIndicator->setOK(keyword_->data().z.isValid()); - - Q_EMIT(keywordDataChanged(keyword_->editSignals())); -} - -/* - * Update - */ - -// Update value displayed in widget -void Vec3NodeValueKeywordWidget::updateValue(const Flags &mutationFlags) -{ - refreshing_ = true; - - ui_.ValueAEdit->setText(QString::fromStdString(keyword_->data().x.asString())); - ui_.ValueAValidIndicator->setOK(keyword_->data().x.isValid()); - ui_.ValueBEdit->setText(QString::fromStdString(keyword_->data().y.asString())); - ui_.ValueBValidIndicator->setOK(keyword_->data().y.isValid()); - ui_.ValueCEdit->setText(QString::fromStdString(keyword_->data().z.asString())); - ui_.ValueCValidIndicator->setOK(keyword_->data().z.isValid()); - - refreshing_ = false; -} diff --git a/src/gui/keywordWidgets/vec3NodeValue.h b/src/gui/keywordWidgets/vec3NodeValue.h deleted file mode 100644 index 13b8ed4ba2..0000000000 --- a/src/gui/keywordWidgets/vec3NodeValue.h +++ /dev/null @@ -1,52 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#pragma once - -#include "gui/keywordWidgets/base.h" -#include "gui/keywordWidgets/ui_vec3NodeValue.h" -#include "keywords/vec3NodeValue.h" -#include - -class Vec3NodeValueKeywordWidget : public QWidget, public KeywordWidgetBase -{ - // All Qt declarations must include this macro - Q_OBJECT - - public: - Vec3NodeValueKeywordWidget(QWidget *parent, Vec3NodeValueKeyword *keyword, const CoreData &coreData); - - /* - * Keyword - */ - private: - // Associated keyword - Vec3NodeValueKeyword *keyword_; - - /* - * Widgets - */ - private: - // Main form declaration - Ui::Vec3NodeValueWidget ui_; - - private Q_SLOTS: - // Values edited - void on_ValueAEdit_editingFinished(); - void on_ValueAEdit_returnPressed(); - void on_ValueBEdit_editingFinished(); - void on_ValueBEdit_returnPressed(); - void on_ValueCEdit_editingFinished(); - void on_ValueCEdit_returnPressed(); - - Q_SIGNALS: - // Keyword data changed - void keywordDataChanged(int flags); - - /* - * Update - */ - public: - // Update value displayed in widget - void updateValue(const Flags &mutationFlags) override; -}; diff --git a/src/gui/keywordWidgets/vec3NodeValue.ui b/src/gui/keywordWidgets/vec3NodeValue.ui deleted file mode 100644 index a75059c04f..0000000000 --- a/src/gui/keywordWidgets/vec3NodeValue.ui +++ /dev/null @@ -1,155 +0,0 @@ - - - Vec3NodeValueWidget - - - - 0 - 0 - 94 - 90 - - - - - 10 - - - - Form - - - - 0 - - - 0 - - - 0 - - - 0 - - - 2 - - - 0 - - - - - - 0 - 0 - - - - - - - - - - - - - - - 0 - 0 - - - - - - - - - - - - 0 - 0 - - - - - - - - - - - - - - - - - - 0 - 0 - - - - - true - - - - A - - - - - - - - 0 - 0 - - - - - true - - - - B - - - - - - - - 0 - 0 - - - - - true - - - - C - - - - - - - - CheckIndicator - QLabel -
gui/widgets/checkIndicator.h
-
-
- - - - -
diff --git a/src/gui/keywordWidgets/weightedModuleVector.cpp b/src/gui/keywordWidgets/weightedModuleVector.cpp deleted file mode 100644 index d86253c7a3..0000000000 --- a/src/gui/keywordWidgets/weightedModuleVector.cpp +++ /dev/null @@ -1,84 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#include "gui/keywordWidgets/weightedModuleVector.h" -#include "classes/coreData.h" -#include "gui/delegates/exponentialSpin.h" -#include "gui/keywordWidgets/dropDown.h" -#include "module/module.h" -#include "templates/algorithms.h" -#include -#include -#include - -WeightedModuleVectorKeywordWidget::WeightedModuleVectorKeywordWidget(QWidget *parent, WeightedModuleVectorKeyword *keyword, - const CoreData &coreData) - : KeywordDropDown(this), KeywordWidgetBase(coreData), keyword_(keyword) -{ - // Create and set up the UI for our widget in the drop-down's widget container - ui_.setupUi(dropWidget()); - - // Set up the model - ui_.ModuleColumns->setModel(&weightedModuleModel_); - weightedModuleModel_.setWeightedItems(keyword_->data()); - resetModelData(); - - // Set delegates - ui_.ModuleColumns->setItemDelegateForColumn(1, new ExponentialSpinDelegate(this)); - - // Connect signals / slots - connect(&weightedModuleModel_, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), this, - SLOT(modelDataChanged(const QModelIndex &, const QModelIndex &))); - - updateSummaryText(); -} - -/* - * Widgets - */ - -// List item changed -void WeightedModuleVectorKeywordWidget::modelDataChanged(const QModelIndex &, const QModelIndex &) -{ - if (refreshing_) - return; - - updateSummaryText(); - - Q_EMIT(keywordDataChanged(keyword_->editSignals())); -} - -/* - * Update - */ - -// Reset model data -void WeightedModuleVectorKeywordWidget::resetModelData() -{ - refreshing_ = true; - - // Update allowed modules - allowedModules_ = coreData_.allOfType(keyword_->moduleTypes()); - weightedModuleModel_.setData(allowedModules_); - - updateSummaryText(); - - refreshing_ = false; -} - -// Update value displayed in widget -void WeightedModuleVectorKeywordWidget::updateValue(const Flags &mutationFlags) -{ - if (mutationFlags.isSet(DissolveSignals::ModulesMutated)) - resetModelData(); -} - -// Update summary text -void WeightedModuleVectorKeywordWidget::updateSummaryText() -{ - if (keyword_->data().empty()) - setSummaryText(""); - else - setSummaryText(QString::fromStdString(joinStrings( - keyword_->data(), ", ", [](const auto &item) { return std::format("{} ({})", item.first->name(), item.second); }))); -} diff --git a/src/gui/keywordWidgets/weightedModuleVector.h b/src/gui/keywordWidgets/weightedModuleVector.h deleted file mode 100644 index 8895289bb3..0000000000 --- a/src/gui/keywordWidgets/weightedModuleVector.h +++ /dev/null @@ -1,61 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#pragma once - -#include "gui/keywordWidgets/base.h" -#include "gui/keywordWidgets/dropDown.h" -#include "gui/keywordWidgets/ui_weightedModuleVector.h" -#include "gui/models/weightedModuleModel.h" -#include "keywords/weightedModuleVector.h" -#include - -// Forward Declarations -class Module; - -class WeightedModuleVectorKeywordWidget : public KeywordDropDown, public KeywordWidgetBase -{ - // All Qt declarations must include this macro - Q_OBJECT - - public: - WeightedModuleVectorKeywordWidget(QWidget *parent, WeightedModuleVectorKeyword *keyword, const CoreData &coreData); - - /* - * Keyword - */ - private: - // Associated keyword - WeightedModuleVectorKeyword *keyword_; - - /* - * Widgets - */ - private: - // Main form declaration - Ui::WeightedModuleVectorWidget ui_; - // Vector of allowed module targets - std::vector allowedModules_; - // Model for combo box - WeightedModuleModel weightedModuleModel_; - - private Q_SLOTS: - void modelDataChanged(const QModelIndex &, const QModelIndex &); - - Q_SIGNALS: - // Keyword data changed - void keywordDataChanged(int flags); - - /* - * Update - */ - private: - // Reset model data - void resetModelData(); - - public: - // Update value displayed in widget - void updateValue(const Flags &mutationFlags) override; - // Update summary text - void updateSummaryText(); -}; diff --git a/src/gui/keywordWidgets/weightedModuleVector.ui b/src/gui/keywordWidgets/weightedModuleVector.ui deleted file mode 100644 index 6c01162cec..0000000000 --- a/src/gui/keywordWidgets/weightedModuleVector.ui +++ /dev/null @@ -1,44 +0,0 @@ - - - WeightedModuleVectorWidget - - - - 0 - 0 - 320 - 162 - - - - - 10 - - - - Form - - - - 0 - - - 0 - - - 0 - - - 0 - - - 4 - - - - - - - - - diff --git a/src/gui/keywordWidgets/widget.cpp b/src/gui/keywordWidgets/widget.cpp deleted file mode 100644 index 7592baf7b5..0000000000 --- a/src/gui/keywordWidgets/widget.cpp +++ /dev/null @@ -1,137 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#include "gui/keywordWidgets/widget.h" -#include "gui/keywordWidgets/producers.h" -#include "gui/keywordWidgets/widgetGroupHeader.h" -#include "gui/signals.h" -#include "main/dissolve.h" -#include "module/module.h" -#include -#include -#include -#include - -KeywordsWidget::KeywordsWidget(QWidget *parent) : QScrollArea(parent) -{ - refreshing_ = false; - - setWidgetResizable(true); -} - -/* - * Controls - */ - -// Set up controls for specified keywords -void KeywordsWidget::setUp(const KeywordStoreSection &keywordSection, CoreData &coreData) -{ - keywordWidgets_.clear(); - - // Create a new QWidget and layout for the next group? - auto *sectionWidget = new QWidget(parentWidget()); - auto *sectionLayout = new QGridLayout(sectionWidget); - auto row = 0; - for (auto &group : keywordSection.groups()) - { - // Nothing to do if this group is hidden - if (group.name() == "_HIDDEN") - continue; - - // Create a widget for the group name - if (group.name() != "_NO_HEADER") - { - auto *groupHeader = new WidgetGroupHeader(QString::fromStdString(std::string(group.name())), - QString::fromStdString(std::string(group.description()))); - - if (row != 0) - groupHeader->setContentsMargins(0, 15, 0, 0); - sectionLayout->addWidget(groupHeader, row++, 0, 1, 2); - } - - // Loop over keywords in the group and add them to our groupbox - for (auto &[keyword, keywordType] : group.keywords()) - { - // Try to create a suitable widget - auto [widget, base] = KeywordWidgetProducer::create(keyword, coreData); - if (!widget || !base) - { - std::cout << std::format("No widget created for keyword '{}'.", keyword->name()) << std::endl; - continue; - } - - // Connect signals - connect(widget, SIGNAL(keywordDataChanged(int)), this, SLOT(keywordDataChanged(int))); - - // Put the widget in a horizontal layout with a stretch to absorb extra space - auto *w = new QHBoxLayout; - w->addWidget(widget, 0); - w->addStretch(1); - - // Create a label and add it and the widget to our layout - auto *nameLabel = new QLabel(QString::fromStdString(std::string(keyword->name()))); - nameLabel->setToolTip(QString::fromStdString(std::string(keyword->description()))); - nameLabel->setContentsMargins(10, 5, 0, 0); - nameLabel->setAlignment(Qt::AlignTop); - sectionLayout->addWidget(nameLabel, row, 0); - sectionLayout->addLayout(w, row++, 1); - - // Push onto our reference list - keywordWidgets_.push_back(base); - } - } - - // Add vertical spacer to the end of the group - sectionLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding), row, 0); - sectionWidget->setLayout(sectionLayout); - setWidget(sectionWidget); -} - -// Create a suitable button for the named group -std::pair KeywordsWidget::buttonForGroup(std::string_view groupName) -{ - // Create basic button - auto *b = new QPushButton(QString::fromStdString(std::string(groupName))); - b->setCheckable(true); - b->setAutoExclusive(true); - b->setFlat(true); - - const std::vector> knownButtons = { - {"Options", ":/general/icons/options.svg", false}, - {"Export", ":/general/icons/save.svg", false}, - {"Advanced", ":/general/icons/advanced.svg", true}, - }; - - // Apply icons / alignment to recognised buttons - bool alignRight = false; - auto it = std::find_if(knownButtons.begin(), knownButtons.end(), - [groupName](const auto &btnData) { return std::get<0>(btnData) == groupName; }); - if (it != knownButtons.end()) - { - b->setIcon(QIcon(std::get<1>(*it))); - alignRight = std::get<2>(*it); - } - - return {b, alignRight}; -} - -// Update controls within widget -void KeywordsWidget::updateControls(int dataMutationFlags) -{ - refreshing_ = true; - - Flags mutationFlags(dataMutationFlags); - - // Update all our keyword widgets - for (auto *keywordWidget : keywordWidgets_) - keywordWidget->updateValue(mutationFlags); - - refreshing_ = false; -} - -/* - * Signals / Slots - */ - -// Keyword data changed -void KeywordsWidget::keywordDataChanged(int keywordSignalMask) { Q_EMIT(keywordChanged(keywordSignalMask)); } diff --git a/src/gui/keywordWidgets/widget.h b/src/gui/keywordWidgets/widget.h deleted file mode 100644 index f0dc2d9f3a..0000000000 --- a/src/gui/keywordWidgets/widget.h +++ /dev/null @@ -1,52 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#pragma once - -#include "gui/keywordWidgets/base.h" -#include "keywords/store.h" -#include - -// Forward Declarations -class CoreData; -class QPushButton; - -// Keywords Widget -class KeywordsWidget : public QScrollArea -{ - Q_OBJECT - - public: - KeywordsWidget(QWidget *parent = nullptr); - ~KeywordsWidget() = default; - - /* - * Controls - */ - private: - // Whether the widget is currently refreshing - bool refreshing_; - // Reference vector of displayed keyword widgets - std::vector keywordWidgets_; - - public: - // Set up controls for specified keywords - void setUp(const KeywordStoreSection &keywordSection, CoreData &coreData); - // Create a suitable button for the named group - static std::pair buttonForGroup(std::string_view groupName); - - public Q_SLOTS: - // Update controls within widget - void updateControls(int dataMutationFlags = 0); - - /* - * Signals / Slots - */ - private Q_SLOTS: - // Keyword data changed - void keywordDataChanged(int keywordSignalMask); - - Q_SIGNALS: - // Keyword has been modified - void keywordChanged(int keywordSignalMask); -}; diff --git a/src/gui/keywordWidgets/widgetGroupHeader.cpp b/src/gui/keywordWidgets/widgetGroupHeader.cpp deleted file mode 100644 index e1ec363999..0000000000 --- a/src/gui/keywordWidgets/widgetGroupHeader.cpp +++ /dev/null @@ -1,16 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#include "gui/keywordWidgets/widgetGroupHeader.h" - -WidgetGroupHeader::WidgetGroupHeader(const QString &groupName, const QString &description) : QWidget() -{ - // Setup our UI - ui_.setupUi(this); - - ui_.GroupLabel->setText(groupName); - if (description.isEmpty()) - ui_.DescriptionLabel->setVisible(false); - else - ui_.DescriptionLabel->setText(description); -} diff --git a/src/gui/keywordWidgets/widgetGroupHeader.h b/src/gui/keywordWidgets/widgetGroupHeader.h deleted file mode 100644 index 75f37f19cb..0000000000 --- a/src/gui/keywordWidgets/widgetGroupHeader.h +++ /dev/null @@ -1,23 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#pragma once - -#include "gui/keywordWidgets/ui_widgetGroupHeader.h" -#include - -class WidgetGroupHeader : public QWidget -{ - // All Qt declarations must include this macro - Q_OBJECT - - public: - WidgetGroupHeader(const QString &groupName, const QString &description = {}); - - /* - * Widgets - */ - private: - // Main form declaration - Ui::GroupHeaderWidget ui_; -}; diff --git a/src/gui/keywordWidgets/widgetGroupHeader.ui b/src/gui/keywordWidgets/widgetGroupHeader.ui deleted file mode 100644 index f47c166147..0000000000 --- a/src/gui/keywordWidgets/widgetGroupHeader.ui +++ /dev/null @@ -1,115 +0,0 @@ - - - GroupHeaderWidget - - - - 0 - 0 - 542 - 47 - - - - - 0 - 0 - - - - - 10 - - - - Form - - - - 4 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - true - - - - 0 - 0 - - - - - 11 - false - false - PreferDefault - true - - - - Group Name - - - - - - - - 0 - 0 - - - - Qt::Horizontal - - - - - - - true - - - - 0 - 0 - - - - - 10 - false - false - PreferDefault - true - - - - Description - - - true - - - - - - - - - - diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 19138f50bf..c9ea7c34d7 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -47,7 +47,7 @@ function(dissolve_add_test) target_include_directories(${TEST_NAME} PRIVATE ${Qt6Widgets_INCLUDE_DIRS}) target_link_libraries( ${TEST_NAME} - PUBLIC keywordWidgets models widgets render delegates + PUBLIC models widgets render delegates PRIVATE Qt6::Core Qt6::Widgets ) endif(DISSOLVE_UNIT_TEST_GUI) diff --git a/tests/gui/CMakeLists.txt b/tests/gui/CMakeLists.txt index 61752cc85c..08aa779315 100644 --- a/tests/gui/CMakeLists.txt +++ b/tests/gui/CMakeLists.txt @@ -4,8 +4,6 @@ dissolve_add_test(SRC forcefieldTab.cpp GUI) dissolve_add_test(SRC isotopologueSetModel.cpp GUI) dissolve_add_test(SRC expressionVariableVectorModel.cpp GUI) dissolve_add_test(SRC masterTerms.cpp GUI) -dissolve_add_test(SRC optionalDoubleKeyword.cpp GUI) -dissolve_add_test(SRC optionalIntegerKeyword.cpp GUI) dissolve_add_test(SRC procedure.cpp GUI) dissolve_add_test(SRC modifyCharges.cpp GUI) dissolve_add_test(SRC speciesTab.cpp GUI) From 38ddd981e3f7ab14776c24186f061ee622157e3e Mon Sep 17 00:00:00 2001 From: Adam Washington Date: Fri, 14 Nov 2025 09:40:17 +0000 Subject: [PATCH 06/31] Start showing species data in gui --- src/gui/CMakeLists.txt | 11 - src/gui/models/dissolveModel.cpp | 5 - src/gui/models/dissolveModel.h | 6 - src/gui/models/speciesBondModel.cpp | 49 +++-- src/gui/models/speciesBondModel.h | 9 +- src/gui/models/speciesModel.cpp | 224 ++++++++++---------- src/gui/models/speciesModel.h | 32 +-- src/gui/qml/nodeGraph/ParameterDelegate.qml | 8 +- tests/gui/speciesTab.cpp | 39 ---- 9 files changed, 166 insertions(+), 217 deletions(-) diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index 5279a15329..cb423fef6b 100755 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -58,9 +58,6 @@ add_library( selectForcefieldWidget.cpp selectForcefieldWidget.h selectForcefieldWidget.ui - selectSpeciesWidget.cpp - selectSpeciesWidget.h - selectSpeciesWidget.ui # Dialogs addConfigurationDialog.cpp addConfigurationDialog.h @@ -96,12 +93,6 @@ add_library( importLigParGenDialog.cpp importLigParGenDialog.h importLigParGenDialog.ui - importSpeciesDialog.cpp - importSpeciesDialog.h - importSpeciesDialog.ui - intramolecularTermsDialog.cpp - intramolecularTermsDialog.h - intramolecularTermsDialog.ui modifyChargesDialog.cpp modifyChargesDialog.h selectAtomTypeDialog.cpp @@ -138,8 +129,6 @@ add_library( messagesTab.cpp messagesTab.h messagesTab.ui - overviewTab.cpp - overviewTab.h speciesTab.cpp speciesTab_geometry.cpp speciesTab_isotopologues.cpp diff --git a/src/gui/models/dissolveModel.cpp b/src/gui/models/dissolveModel.cpp index 9f235aed1c..3ef9f3d045 100644 --- a/src/gui/models/dissolveModel.cpp +++ b/src/gui/models/dissolveModel.cpp @@ -22,7 +22,6 @@ void DissolveModel::setDissolve(Dissolve &dissolve) dissolve_ = &dissolve; atomTypes_.setData(dissolve_->coreData().atomTypes()); masters_ = std::make_unique(dissolve_->coreData()); - speciesModel_.setData(dissolve_->coreData().species()); configurationModel_.setData(dissolve_->coreData().configurations()); moduleLayersModel_.setData(dissolve_->coreData().processingLayers(), &dissolve_->coreData()); Q_EMIT modelsUpdated(); @@ -39,7 +38,6 @@ void DissolveModel::update() masters_->torsionModel_.reset(); masters_->improperModel_.reset(); } - speciesModel_.reset(); configurationModel_.reset(); moduleLayersModel_.reset(); Q_EMIT modelsUpdated(); @@ -115,9 +113,6 @@ int DissolveModel::nMasterImpropers() return masters_->improperModel_.rowCount(); } -// The Species Model -SpeciesModel *DissolveModel::speciesModel() { return &speciesModel_; } - // The Configuration Model ConfigurationModel *DissolveModel::configurationsModel() { return &configurationModel_; } diff --git a/src/gui/models/dissolveModel.h b/src/gui/models/dissolveModel.h index 8fb202ad4b..43b4dfcfe6 100644 --- a/src/gui/models/dissolveModel.h +++ b/src/gui/models/dissolveModel.h @@ -7,7 +7,6 @@ #include "gui/models/configurationModel.h" #include "gui/models/masterTermTreeModel.h" #include "gui/models/moduleLayersModel.h" -#include "gui/models/speciesModel.h" #include "main/dissolve.h" #include "nodes/graph.h" #include "templates/optionalRef.h" @@ -27,8 +26,6 @@ class DissolveModel : public QObject Q_PROPERTY(const MasterTorsionModel *masterTorsionsModel READ masterTorsionsModel NOTIFY mastersChanged) // The Master Improper Model Q_PROPERTY(const MasterImproperModel *masterImpropersModel READ masterImpropersModel NOTIFY mastersChanged) - // The Species Model - Q_PROPERTY(const SpeciesModel *speciesModel READ speciesModel NOTIFY speciesChanged) // The Configuration Model Q_PROPERTY(const ConfigurationModel *configurationsModel READ configurationsModel NOTIFY configurationsChanged) // The ModuleLayers Model @@ -43,7 +40,6 @@ class DissolveModel : public QObject AtomTypeModel atomTypes_; // Master terms model std::unique_ptr masters_ = nullptr; - SpeciesModel speciesModel_; ConfigurationModel configurationModel_; ModuleLayersModel moduleLayersModel_; @@ -98,8 +94,6 @@ class DissolveModel : public QObject const MasterImproperModel *masterImpropersModel() const; // The number of master impropers int nMasterImpropers(); - // The Species Model - SpeciesModel *speciesModel(); // The Configurations Model ConfigurationModel *configurationsModel(); // The ModuleLayers Model diff --git a/src/gui/models/speciesBondModel.cpp b/src/gui/models/speciesBondModel.cpp index b2791ac59b..a548d55505 100644 --- a/src/gui/models/speciesBondModel.cpp +++ b/src/gui/models/speciesBondModel.cpp @@ -2,23 +2,28 @@ // Copyright (c) 2025 Team Dissolve and contributors #include "gui/models/speciesBondModel.h" -#include "classes/coreData.h" -SpeciesBondModel::SpeciesBondModel(std::vector &bonds, const CoreData &coreData) - : bonds_(bonds), coreData_(coreData) +SpeciesBondModel::SpeciesBondModel() : bonds_(nullptr) {} + +void SpeciesBondModel::reset() { + beginResetModel(); + endResetModel(); } -void SpeciesBondModel::reset() +void SpeciesBondModel::setBonds(std::vector &bonds) { beginResetModel(); + bonds_ = &bonds; endResetModel(); } int SpeciesBondModel::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent); - return bonds_.size(); + if (!bonds_) + return 0; + return bonds_->size(); } int SpeciesBondModel::columnCount(const QModelIndex &parent) const @@ -32,7 +37,10 @@ QVariant SpeciesBondModel::data(const QModelIndex &index, int role) const if (role == Qt::ToolTipRole) return headerData(index.column(), Qt::Horizontal, Qt::DisplayRole); - auto &bond = bonds_[index.row()]; + if (!bonds_) + return {}; + + auto &bond = bonds_->at(index.row()); if (role == Qt::DisplayRole || role == Qt::EditRole) switch (index.column()) @@ -78,40 +86,31 @@ Qt::ItemFlags SpeciesBondModel::flags(const QModelIndex &index) const { if (index.column() <= DataType::IndexJ) return Qt::ItemIsSelectable | Qt::ItemIsEnabled; - if (index.column() > DataType::Form && bonds_[index.row()].masterTerm()) + if (index.column() > DataType::Form && bonds_->at(index.row()).masterTerm()) return Qt::ItemIsSelectable | Qt::ItemIsEnabled; return Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled; } bool SpeciesBondModel::setData(const QModelIndex &index, const QVariant &value, int role) { - auto &bond = bonds_[index.row()]; + if (!bonds_) + return false; + auto &bond = bonds_->at(index.row()); switch (index.column()) { case (DataType::IndexI): case (DataType::IndexJ): return false; case (DataType::Form): - if (value.toString().at(0) == '@') + try { - auto master = coreData_.getMasterBond(value.toString().toStdString()); - if (master) - bond.setMasterTerm(&master->get()); - else - return false; + auto bf = BondFunctions::forms().enumeration(value.toString().toStdString()); + bond.detachFromMasterTerm(); + bond.setInteractionForm(bf); } - else + catch (std::runtime_error &e) { - try - { - auto bf = BondFunctions::forms().enumeration(value.toString().toStdString()); - bond.detachFromMasterTerm(); - bond.setInteractionForm(bf); - } - catch (std::runtime_error &e) - { - return false; - } + return false; } break; case (DataType::Parameters): diff --git a/src/gui/models/speciesBondModel.h b/src/gui/models/speciesBondModel.h index 65719b6721..812e30d18f 100644 --- a/src/gui/models/speciesBondModel.h +++ b/src/gui/models/speciesBondModel.h @@ -7,9 +7,6 @@ #include #include -// Forward Declarations -class CoreData; - class SpeciesBondModel : public QAbstractTableModel { Q_OBJECT @@ -25,12 +22,12 @@ class SpeciesBondModel : public QAbstractTableModel }; private: - std::vector &bonds_; - const CoreData &coreData_; + std::vector *bonds_; public: - SpeciesBondModel(std::vector &bonds, const CoreData &coreData); + SpeciesBondModel(); void reset(); + void setBonds(std::vector &bonds); int rowCount(const QModelIndex &parent = QModelIndex()) const override; int columnCount(const QModelIndex &parent = QModelIndex()) const override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; diff --git a/src/gui/models/speciesModel.cpp b/src/gui/models/speciesModel.cpp index f32177ef5e..15bf40a947 100644 --- a/src/gui/models/speciesModel.cpp +++ b/src/gui/models/speciesModel.cpp @@ -3,120 +3,124 @@ #include "gui/models/speciesModel.h" -// Set source Species data -void SpeciesModel::setData(const std::vector> &species) -{ - beginResetModel(); - species_ = species; - endResetModel(); -} - -// Set vector containing checked items -void SpeciesModel::setCheckStateData(std::vector &checkedItemsVector) -{ - beginResetModel(); - checkedItems_ = checkedItemsVector; - endResetModel(); -} - -const Species *SpeciesModel::rawData(const QModelIndex &index) const -{ - assert(species_); - return species_->get()[index.row()].get(); -} - -// Refresh model data -void SpeciesModel::reset() -{ - beginResetModel(); - endResetModel(); -} - -/* - * QAbstractItemModel overrides - */ - -int SpeciesModel::rowCount(const QModelIndex &parent) const -{ - Q_UNUSED(parent); - return species_ ? species_->get().size() : 0; -} - -QVariant SpeciesModel::data(const QModelIndex &index, int role) const +SpeciesModel::SpeciesModel() { - if (!index.isValid()) - return {}; - switch (role) - { - case (Qt::DisplayRole): - return QString::fromStdString(std::string(rawData(index)->name())); - case (Qt::CheckStateRole): - if (checkedItems_) - { - return std::find(checkedItems_->get().begin(), checkedItems_->get().end(), rawData(index)) == - checkedItems_->get().end() - ? Qt::Unchecked - : Qt::Checked; - } - else - { - return {}; - } - case (static_cast(SpeciesUserRole::RawData)): - return QVariant::fromValue(rawData(index)); - case (static_cast(SpeciesUserRole::BondsCount)): - return QVariant::fromValue(rawData(index)->nBonds()); - case (static_cast(SpeciesUserRole::AnglesCount)): - return QVariant::fromValue(rawData(index)->nAngles()); - case (static_cast(SpeciesUserRole::TorsionsCount)): - return QVariant::fromValue(rawData(index)->nTorsions()); - case (static_cast(SpeciesUserRole::ImpropersCount)): - return QVariant::fromValue(rawData(index)->nImpropers()); - default: - return {}; - } + species_ = std::make_shared(); + bonds_.setBonds(species_->bonds()); } -bool SpeciesModel::setData(const QModelIndex &index, const QVariant &value, int role) -{ - if (role == Qt::CheckStateRole && checkedItems_) - { - auto &xitems = checkedItems_->get(); - if (value.value() == Qt::Checked) - { - if (std::find(xitems.begin(), xitems.end(), rawData(index)) == xitems.end()) - xitems.push_back(rawData(index)); - } - else - xitems.erase(std::remove(xitems.begin(), xitems.end(), rawData(index)), xitems.end()); - - Q_EMIT dataChanged(index, index); - - return true; - } - - return false; -} +// Access source Species data +std::shared_ptr SpeciesModel::species() { return species_; } -Qt::ItemFlags SpeciesModel::flags(const QModelIndex &index) const +// Set source Species data +void SpeciesModel::setSpecies(std::shared_ptr species) { - return checkedItems_ ? Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable - : Qt::ItemIsSelectable | Qt::ItemIsEnabled; + species_ = species; + bonds_.setBonds(species_->bonds()); + Q_EMIT(speciesChanged()); } -QVariant SpeciesModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if (role != Qt::DisplayRole) - return {}; - - if (orientation == Qt::Horizontal) - switch (section) - { - case 0: - return "Name"; - default: - return {}; - } - - return {}; -} +// Bond information +SpeciesBondModel *SpeciesModel::bonds() { return &bonds_; } + +// const Species *SpeciesModel::rawData(const QModelIndex &index) const +// { +// assert(species_); +// return species_->get()[index.row()].get(); +// } + +// // Refresh model data +// void SpeciesModel::reset() +// { +// beginResetModel(); +// endResetModel(); +// } + +// /* +// * QAbstractItemModel overrides +// */ + +// int SpeciesModel::rowCount(const QModelIndex &parent) const +// { +// Q_UNUSED(parent); +// return species_ ? species_->get().size() : 0; +// } + +// QVariant SpeciesModel::data(const QModelIndex &index, int role) const +// { +// if (!index.isValid()) +// return {}; +// switch (role) +// { +// case (Qt::DisplayRole): +// return QString::fromStdString(std::string(rawData(index)->name())); +// case (Qt::CheckStateRole): +// if (checkedItems_) +// { +// return std::find(checkedItems_->get().begin(), checkedItems_->get().end(), rawData(index)) == +// checkedItems_->get().end() +// ? Qt::Unchecked +// : Qt::Checked; +// } +// else +// { +// return {}; +// } +// case (static_cast(SpeciesUserRole::RawData)): +// return QVariant::fromValue(rawData(index)); +// case (static_cast(SpeciesUserRole::BondsCount)): +// return QVariant::fromValue(rawData(index)->nBonds()); +// case (static_cast(SpeciesUserRole::AnglesCount)): +// return QVariant::fromValue(rawData(index)->nAngles()); +// case (static_cast(SpeciesUserRole::TorsionsCount)): +// return QVariant::fromValue(rawData(index)->nTorsions()); +// case (static_cast(SpeciesUserRole::ImpropersCount)): +// return QVariant::fromValue(rawData(index)->nImpropers()); +// default: +// return {}; +// } +// } + +// bool SpeciesModel::setData(const QModelIndex &index, const QVariant &value, int role) +// { +// if (role == Qt::CheckStateRole && checkedItems_) +// { +// auto &xitems = checkedItems_->get(); +// if (value.value() == Qt::Checked) +// { +// if (std::find(xitems.begin(), xitems.end(), rawData(index)) == xitems.end()) +// xitems.push_back(rawData(index)); +// } +// else +// xitems.erase(std::remove(xitems.begin(), xitems.end(), rawData(index)), xitems.end()); + +// Q_EMIT dataChanged(index, index); + +// return true; +// } + +// return false; +// } + +// Qt::ItemFlags SpeciesModel::flags(const QModelIndex &index) const +// { +// return checkedItems_ ? Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable +// : Qt::ItemIsSelectable | Qt::ItemIsEnabled; +// } + +// QVariant SpeciesModel::headerData(int section, Qt::Orientation orientation, int role) const +// { +// if (role != Qt::DisplayRole) +// return {}; + +// if (orientation == Qt::Horizontal) +// switch (section) +// { +// case 0: +// return "Name"; +// default: +// return {}; +// } + +// return {}; +// } diff --git a/src/gui/models/speciesModel.h b/src/gui/models/speciesModel.h index b3fcf5124d..60864da60d 100644 --- a/src/gui/models/speciesModel.h +++ b/src/gui/models/speciesModel.h @@ -4,21 +4,26 @@ #pragma once #include "classes/species.h" +#include "gui/models/speciesBondModel.h" #include "templates/optionalRef.h" #include #include +#include #include -class SpeciesModel : public QAbstractListModel +class SpeciesModel : public QObject { Q_OBJECT + // The Species being modelled + Q_PROPERTY(std::shared_ptr species READ species WRITE setSpecies NOTIFY speciesChanged) + Q_PROPERTY(SpeciesBondModel *bonds READ bonds) private: // Source Species data - OptionalReferenceWrapper>> species_; - // Vector containing checked items (if relevant) - OptionalReferenceWrapper> checkedItems_; + std::shared_ptr species_; + // Bond Model + SpeciesBondModel bonds_; // Return object represented by specified model index const Species *rawData(const QModelIndex &index) const; @@ -34,20 +39,19 @@ class SpeciesModel : public QAbstractListModel Q_ENUM(SpeciesUserRole); public: + SpeciesModel(); // Set source Species data - void setData(const std::vector> &species); + void setSpecies(std::shared_ptr species); + // Set source Species data + std::shared_ptr species(); + // Bond information + SpeciesBondModel *bonds(); // Set vector containing checked items void setCheckStateData(std::vector &checkedItemsVector); // Refresh model data void reset(); - /* - * QAbstractItemModel overrides - */ - public: - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; - Qt::ItemFlags flags(const QModelIndex &index) const override; - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + Q_SIGNALS: + // We've changed the underlying species + void speciesChanged(); }; diff --git a/src/gui/qml/nodeGraph/ParameterDelegate.qml b/src/gui/qml/nodeGraph/ParameterDelegate.qml index 9d9e5fe592..d6628c6ebd 100644 --- a/src/gui/qml/nodeGraph/ParameterDelegate.qml +++ b/src/gui/qml/nodeGraph/ParameterDelegate.qml @@ -2,6 +2,7 @@ import QtQuick import QtQuick.Controls import QtQuick.Layouts import Qt.labs.qmlmodels +import Dissolve DelegateChooser { id: root @@ -74,8 +75,13 @@ DelegateChooser { DelegateChoice { roleValue: "species" + Button { - text: "It's a species" + SpeciesModel { + id: sp + species: param + } + text: "It's a species: " + sp.bonds.rowCount() } } DelegateChoice { diff --git a/tests/gui/speciesTab.cpp b/tests/gui/speciesTab.cpp index 1fc924b069..6e95598a42 100644 --- a/tests/gui/speciesTab.cpp +++ b/tests/gui/speciesTab.cpp @@ -74,45 +74,6 @@ TEST_F(SpeciesTabTest, Atoms) EXPECT_EQ(atom.data(atom.index(6, i)).toDouble(), i); } -TEST_F(SpeciesTabTest, Bonds) -{ - CoreData coreData; - Dissolve dissolve(coreData); - - ASSERT_TRUE(dissolve.loadInput("dissolve/input/full-benzene.txt")); - auto &species = coreData.species()[0]; - - SpeciesBondModel bond(species->bonds(), coreData); - - // Test Bonds - EXPECT_EQ(bond.columnCount(), 4); - EXPECT_EQ(bond.rowCount(), 12); - - for (auto role : roles) - { - EXPECT_EQ(bond.data(bond.index(3, 0), role).toInt(), 4); - EXPECT_EQ(bond.data(bond.index(3, 1), role).toInt(), 5); - EXPECT_EQ(bond.data(bond.index(3, 2), role).toString().toStdString(), "@CA-CA"); - EXPECT_EQ(bond.data(bond.index(3, 3), role).toString().toStdString(), "k=3924.59 eq=1.4"); - } - - // Mutate bond - EXPECT_FALSE(bond.setData(bond.index(3, 0), 5)); - EXPECT_FALSE(bond.setData(bond.index(3, 1), 6)); - - EXPECT_FALSE(bond.setData(bond.index(3, 3), "4, 5")); - - EXPECT_FALSE(bond.setData(bond.index(3, 2), "Undefined")); - EXPECT_TRUE(bond.setData(bond.index(3, 2), "Harmonic")); - - EXPECT_TRUE(bond.setData(bond.index(3, 3), "4.0 5.0")); - EXPECT_THAT(bond.data(bond.index(3, 3)).toString().toStdString(), - testing::AnyOf(testing::Eq("k=4.0 eq=5.0"), testing::Eq("k=4 eq=5"))); - - EXPECT_TRUE(bond.setData(bond.index(3, 2), "@CA-CA")); - EXPECT_EQ(bond.data(bond.index(3, 3)).toString().toStdString(), "k=3924.59 eq=1.4"); -} - TEST_F(SpeciesTabTest, Angles) { CoreData coreData; From 972b5b9392b33853c3a572e107d6774cd6b6f406 Mon Sep 17 00:00:00 2001 From: Adam Washington Date: Fri, 14 Nov 2025 11:13:52 +0000 Subject: [PATCH 07/31] Start creating species dialog --- CMakeLists.txt | 1 + src/gui/models/speciesModel.cpp | 8 ++++++ src/gui/models/speciesModel.h | 7 ++++++ src/gui/qml/nodeGraph/ParameterDelegate.qml | 8 +++--- src/gui/qml/nodeGraph/SpeciesDialog.qml | 28 +++++++++++++++++++++ 5 files changed, 48 insertions(+), 4 deletions(-) create mode 100644 src/gui/qml/nodeGraph/SpeciesDialog.qml diff --git a/CMakeLists.txt b/CMakeLists.txt index 964eb66489..a794ffab74 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -268,6 +268,7 @@ if(GUI) ${SRCS}/gui/qml/nodeGraph/GraphDelegate.qml ${SRCS}/gui/qml/nodeGraph/ParameterDelegate.qml ${SRCS}/gui/qml/nodeGraph/NodeBox.qml + ${SRCS}/gui/qml/nodeGraph/SpeciesDialog.qml RESOURCES ) diff --git a/src/gui/models/speciesModel.cpp b/src/gui/models/speciesModel.cpp index 15bf40a947..2107012349 100644 --- a/src/gui/models/speciesModel.cpp +++ b/src/gui/models/speciesModel.cpp @@ -20,6 +20,14 @@ void SpeciesModel::setSpecies(std::shared_ptr species) Q_EMIT(speciesChanged()); } +QString SpeciesModel::name() { return QString::fromStdString(std::string(species_->name())); } + +void SpeciesModel::setName(QString name) +{ + species_->setName(name.toStdString()); + Q_EMIT(nameChanged()); +} + // Bond information SpeciesBondModel *SpeciesModel::bonds() { return &bonds_; } diff --git a/src/gui/models/speciesModel.h b/src/gui/models/speciesModel.h index 60864da60d..2584801154 100644 --- a/src/gui/models/speciesModel.h +++ b/src/gui/models/speciesModel.h @@ -18,6 +18,7 @@ class SpeciesModel : public QObject // The Species being modelled Q_PROPERTY(std::shared_ptr species READ species WRITE setSpecies NOTIFY speciesChanged) Q_PROPERTY(SpeciesBondModel *bonds READ bonds) + Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) private: // Source Species data @@ -44,6 +45,10 @@ class SpeciesModel : public QObject void setSpecies(std::shared_ptr species); // Set source Species data std::shared_ptr species(); + // Species name + QString name(); + // Species name + void setName(QString name); // Bond information SpeciesBondModel *bonds(); // Set vector containing checked items @@ -54,4 +59,6 @@ class SpeciesModel : public QObject Q_SIGNALS: // We've changed the underlying species void speciesChanged(); + // The name has changed + void nameChanged(); }; diff --git a/src/gui/qml/nodeGraph/ParameterDelegate.qml b/src/gui/qml/nodeGraph/ParameterDelegate.qml index d6628c6ebd..6e1de46f01 100644 --- a/src/gui/qml/nodeGraph/ParameterDelegate.qml +++ b/src/gui/qml/nodeGraph/ParameterDelegate.qml @@ -75,13 +75,13 @@ DelegateChooser { DelegateChoice { roleValue: "species" - Button { - SpeciesModel { - id: sp + SpeciesDialog { + id: speciesDialog species: param } - text: "It's a species: " + sp.bonds.rowCount() + text: "Edit" + onClicked: speciesDialog.open() } } DelegateChoice { diff --git a/src/gui/qml/nodeGraph/SpeciesDialog.qml b/src/gui/qml/nodeGraph/SpeciesDialog.qml new file mode 100644 index 0000000000..0ebf94e1e2 --- /dev/null +++ b/src/gui/qml/nodeGraph/SpeciesDialog.qml @@ -0,0 +1,28 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Qt.labs.qmlmodels +import Dissolve + + +Dialog { + id: root + required property variant species; + + standardButtons: Dialog.Ok + title: "Define Species: " + sp.name + + SpeciesModel { + id: sp + species: root.species + } + GridLayout { + columns: 2 + anchors.fill: parent + Text { text: "Name" } + TextField { + placeholderText: sp.name + onTextChanged: sp.name = text + } + } +} From 3bb3e410850984d482e40e0b21ef6da1eaefd72f Mon Sep 17 00:00:00 2001 From: Adam Washington Date: Fri, 14 Nov 2025 12:13:26 +0000 Subject: [PATCH 08/31] Start displaying all species information --- src/gui/qml/nodeGraph/SpeciesDialog.qml | 43 +++++++++++++++++++++---- 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/src/gui/qml/nodeGraph/SpeciesDialog.qml b/src/gui/qml/nodeGraph/SpeciesDialog.qml index 0ebf94e1e2..168e0a0336 100644 --- a/src/gui/qml/nodeGraph/SpeciesDialog.qml +++ b/src/gui/qml/nodeGraph/SpeciesDialog.qml @@ -16,13 +16,42 @@ Dialog { id: sp species: root.species } - GridLayout { - columns: 2 - anchors.fill: parent - Text { text: "Name" } - TextField { - placeholderText: sp.name - onTextChanged: sp.name = text + ColumnLayout { + RowLayout { + Text {text: "Name"} + TextField { + placeholderText: sp.name + onTextChanged: sp.name = text + } + } + GroupBox { + id: atomBox + title: "Atoms" + } + GridLayout { + columns: 2 + GroupBox { + title: "Bonds" + TableView { + model: sp.bonds + delegate: Rectangle { + implicitWidth: 100 + implicitHeight: 50 + Text { + text: display + } + } + } + } + GroupBox { + title: "Angles" + } + GroupBox { + title: "Torsions" + } + GroupBox { + title: "Impropers" + } } } } From 6426b7659ae4506c71c00973d39ab0d010483dcb Mon Sep 17 00:00:00 2001 From: Adam Washington Date: Fri, 14 Nov 2025 13:36:26 +0000 Subject: [PATCH 09/31] Display atom type information --- src/gui/CMakeLists.txt | 6 --- src/gui/models/speciesAtomModel.cpp | 54 +++++++++++++------ src/gui/models/speciesAtomModel.h | 14 +++-- src/gui/models/speciesModel.cpp | 12 +++-- src/gui/models/speciesModel.h | 9 +++- src/gui/qml/nodeGraph/SpeciesDialog.qml | 45 ++++++++++++++-- .../SimulationDataManager.qml | 2 + tests/gui/CMakeLists.txt | 1 - 8 files changed, 104 insertions(+), 39 deletions(-) diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index cb423fef6b..de2ac8fd12 100755 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -129,12 +129,6 @@ add_library( messagesTab.cpp messagesTab.h messagesTab.ui - speciesTab.cpp - speciesTab_geometry.cpp - speciesTab_isotopologues.cpp - speciesTab_sites.cpp - speciesTab.h - speciesTab.ui # Main UI gui.cpp gui_simulation.cpp diff --git a/src/gui/models/speciesAtomModel.cpp b/src/gui/models/speciesAtomModel.cpp index fbd257a998..e151633866 100644 --- a/src/gui/models/speciesAtomModel.cpp +++ b/src/gui/models/speciesAtomModel.cpp @@ -1,12 +1,26 @@ #include "gui/models/speciesAtomModel.h" -#include "classes/atomType.h" +#include "classes/species.h" +#include "data/elements.h" -SpeciesAtomModel::SpeciesAtomModel(Species &species, const CoreData &coreData) : species_(species), coreData_(coreData) {} +SpeciesAtomModel::SpeciesAtomModel() {} + +void SpeciesAtomModel::setSpecies(std::shared_ptr species) { species_ = species; } + +void SpeciesAtomModel::addAtom(QString element, double x, double y, double z, double charge) +{ + auto Z = Elements::element(element.toStdString()); + Vector3 r{x, y, z}; + beginInsertRows({}, species_->atoms().size(), species_->atoms().size()); + species_->addAtom(Z, r, charge); + endInsertRows(); +} int SpeciesAtomModel::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent); - return species_.atoms().size(); + if (!species_) + return 0; + return species_->atoms().size(); } int SpeciesAtomModel::columnCount(const QModelIndex &parent) const @@ -20,7 +34,10 @@ QVariant SpeciesAtomModel::data(const QModelIndex &index, int role) const if (role == Qt::ToolTipRole) return headerData(index.column(), Qt::Horizontal, Qt::DisplayRole); - auto &item = species_.atom(index.row()); + if (!species_) + return {}; + + auto &item = species_->atom(index.row()); if (role == Qt::UserRole) return QVariant::fromValue(&item); @@ -82,33 +99,36 @@ bool SpeciesAtomModel::setData(const QModelIndex &index, const QVariant &value, { if (role != Qt::EditRole) return false; - auto &item = species_.atom(index.row()); + if (!species_) + return false; + auto &item = species_->atom(index.row()); switch (index.column()) { case 0: return false; case 1: - // TODO - { - auto atomType = coreData_.findAtomType(value.toString().toStdString()); - if (!atomType) - return false; - item.setAtomType(atomType); - species_.updateIsotopologues(); - Q_EMIT atomTypeChanged(); - } - break; + return false; + // FIXME: we don't have atom types yet + // { + // auto atomType = coreData_.findAtomType(value.toString().toStdString()); + // if (!atomType) + // return false; + // item.setAtomType(atomType); + // species_->updateIsotopologues(); + // Q_EMIT atomTypeChanged(); + // } + // break; case 2: case 3: case 4: { auto newR = item.r(); newR.set(index.column() - 2, value.toDouble()); - species_.setAtomCoordinates(&item, newR); + species_->setAtomCoordinates(&item, newR); } break; case 5: - species_.setAtomCharge(&item, value.toDouble()); + species_->setAtomCharge(&item, value.toDouble()); break; } Q_EMIT dataChanged(index, index); diff --git a/src/gui/models/speciesAtomModel.h b/src/gui/models/speciesAtomModel.h index 31530dc4f6..d4e955b59f 100644 --- a/src/gui/models/speciesAtomModel.h +++ b/src/gui/models/speciesAtomModel.h @@ -3,24 +3,28 @@ #pragma once -#include "classes/speciesAtom.h" -#include "main/dissolve.h" #include #include +class Species; + class SpeciesAtomModel : public QAbstractTableModel { Q_OBJECT private: - Species &species_; - const CoreData &coreData_; + std::shared_ptr species_; Q_SIGNALS: void atomTypeChanged(); + public Q_SLOTS: + void addAtom(QString element, double x, double y, double z, double charge); + public: - SpeciesAtomModel(Species &species, const CoreData &coreData); + SpeciesAtomModel(); + + void setSpecies(std::shared_ptr species); int rowCount(const QModelIndex &parent = QModelIndex()) const override; diff --git a/src/gui/models/speciesModel.cpp b/src/gui/models/speciesModel.cpp index 2107012349..d0cb822648 100644 --- a/src/gui/models/speciesModel.cpp +++ b/src/gui/models/speciesModel.cpp @@ -2,12 +2,10 @@ // Copyright (c) 2025 Team Dissolve and contributors #include "gui/models/speciesModel.h" +#include "speciesAtomModel.h" +#include -SpeciesModel::SpeciesModel() -{ - species_ = std::make_shared(); - bonds_.setBonds(species_->bonds()); -} +SpeciesModel::SpeciesModel() { species_ = std::make_shared(); } // Access source Species data std::shared_ptr SpeciesModel::species() { return species_; } @@ -17,6 +15,7 @@ void SpeciesModel::setSpecies(std::shared_ptr species) { species_ = species; bonds_.setBonds(species_->bonds()); + atoms_.setSpecies(species_); Q_EMIT(speciesChanged()); } @@ -31,6 +30,9 @@ void SpeciesModel::setName(QString name) // Bond information SpeciesBondModel *SpeciesModel::bonds() { return &bonds_; } +// Atom information +SpeciesAtomModel *SpeciesModel::atoms() { return &atoms_; } + // const Species *SpeciesModel::rawData(const QModelIndex &index) const // { // assert(species_); diff --git a/src/gui/models/speciesModel.h b/src/gui/models/speciesModel.h index 2584801154..ef64140c8c 100644 --- a/src/gui/models/speciesModel.h +++ b/src/gui/models/speciesModel.h @@ -4,8 +4,8 @@ #pragma once #include "classes/species.h" +#include "gui/models/speciesAtomModel.h" #include "gui/models/speciesBondModel.h" -#include "templates/optionalRef.h" #include #include @@ -17,12 +17,15 @@ class SpeciesModel : public QObject Q_OBJECT // The Species being modelled Q_PROPERTY(std::shared_ptr species READ species WRITE setSpecies NOTIFY speciesChanged) - Q_PROPERTY(SpeciesBondModel *bonds READ bonds) + Q_PROPERTY(SpeciesAtomModel *atoms READ atoms NOTIFY speciesChanged) + Q_PROPERTY(SpeciesBondModel *bonds READ bonds NOTIFY speciesChanged) Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) private: // Source Species data std::shared_ptr species_; + // Atom Model + SpeciesAtomModel atoms_; // Bond Model SpeciesBondModel bonds_; // Return object represented by specified model index @@ -49,6 +52,8 @@ class SpeciesModel : public QObject QString name(); // Species name void setName(QString name); + // Atom information + SpeciesAtomModel *atoms(); // Bond information SpeciesBondModel *bonds(); // Set vector containing checked items diff --git a/src/gui/qml/nodeGraph/SpeciesDialog.qml b/src/gui/qml/nodeGraph/SpeciesDialog.qml index 168e0a0336..3e68ceac5a 100644 --- a/src/gui/qml/nodeGraph/SpeciesDialog.qml +++ b/src/gui/qml/nodeGraph/SpeciesDialog.qml @@ -26,14 +26,53 @@ Dialog { } GroupBox { id: atomBox - title: "Atoms" + title: "Atoms (" + sp.atoms.rowCount() + ")" + ColumnLayout { + RowLayout { + Button { + text: "+" + onClicked: sp.atoms.addAtom(elementField.text, xField.text, yField.text, zField.text, chargeField.text); + } + Text { text: "Element" } + TextField { id: elementField } + Text { text: "X" } + TextField { id: xField } + Text { text: "Y" } + TextField { id: yField } + Text { text: "Z" } + TextField { id: zField } + Text { text: "Charge" } + TextField { id: chargeField } + } + TableView { + Layout.fillHeight: true + Layout.fillWidth: true + implicitHeight: 400 + clip: true + columnSpacing: 1 + rowSpacing: 1 + + model: sp.atoms + + delegate: Rectangle { + color: "white" + implicitWidth: 100 + implicitHeight: 50 + border.width: 1 + Text { + text: display + anchors.centerIn: parent + } + } + } + } } GridLayout { columns: 2 GroupBox { - title: "Bonds" + title: "Bonds (" + sp.bonds.rowCount() + ")" TableView { - model: sp.bonds + model: sp.atoms delegate: Rectangle { implicitWidth: 100 implicitHeight: 50 diff --git a/src/gui/qml/simulationDataManager/SimulationDataManager.qml b/src/gui/qml/simulationDataManager/SimulationDataManager.qml index 6e35278d1a..067c488e51 100644 --- a/src/gui/qml/simulationDataManager/SimulationDataManager.qml +++ b/src/gui/qml/simulationDataManager/SimulationDataManager.qml @@ -59,6 +59,7 @@ Page { } TableView { id: table + anchors.fill: parent property variant colWidths: [300, 300, 50] @@ -70,6 +71,7 @@ Page { columnWidthProvider: function (column) { return colWidths[column]; } + model: proxy rowSpacing: 1 diff --git a/tests/gui/CMakeLists.txt b/tests/gui/CMakeLists.txt index 08aa779315..15d953151f 100644 --- a/tests/gui/CMakeLists.txt +++ b/tests/gui/CMakeLists.txt @@ -6,5 +6,4 @@ dissolve_add_test(SRC expressionVariableVectorModel.cpp GUI) dissolve_add_test(SRC masterTerms.cpp GUI) dissolve_add_test(SRC procedure.cpp GUI) dissolve_add_test(SRC modifyCharges.cpp GUI) -dissolve_add_test(SRC speciesTab.cpp GUI) dissolve_add_test(SRC xmlForcefield.cpp GUI) From d1f208769406a141bef29130005b17342992a162 Mon Sep 17 00:00:00 2001 From: Adam Washington Date: Fri, 14 Nov 2025 18:38:14 +0000 Subject: [PATCH 10/31] Add Element Combo Box --- CMakeLists.txt | 1 + src/gui/qml/nodeGraph/ElementComboBox.qml | 130 ++++++++++++++++++++++ src/gui/qml/nodeGraph/SpeciesDialog.qml | 8 +- 3 files changed, 135 insertions(+), 4 deletions(-) create mode 100644 src/gui/qml/nodeGraph/ElementComboBox.qml diff --git a/CMakeLists.txt b/CMakeLists.txt index a794ffab74..f278861ff5 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -269,6 +269,7 @@ if(GUI) ${SRCS}/gui/qml/nodeGraph/ParameterDelegate.qml ${SRCS}/gui/qml/nodeGraph/NodeBox.qml ${SRCS}/gui/qml/nodeGraph/SpeciesDialog.qml + ${SRCS}/gui/qml/nodeGraph/ElementComboBox.qml RESOURCES ) diff --git a/src/gui/qml/nodeGraph/ElementComboBox.qml b/src/gui/qml/nodeGraph/ElementComboBox.qml new file mode 100644 index 0000000000..ea926d9ca5 --- /dev/null +++ b/src/gui/qml/nodeGraph/ElementComboBox.qml @@ -0,0 +1,130 @@ +import QtQuick +import QtQuick.Controls +import Qt.labs.qmlmodels + + +ComboBox { + editable: true + model: ListModel { + id: model + ListElement { text: "H" } + ListElement { text: "He" } + ListElement { text: "Li" } + ListElement { text: "Be" } + ListElement { text: "B" } + ListElement { text: "C" } + ListElement { text: "N" } + ListElement { text: "O" } + ListElement { text: "F" } + ListElement { text: "Ne" } + ListElement { text: "Na" } + ListElement { text: "Mg" } + ListElement { text: "Al" } + ListElement { text: "Si" } + ListElement { text: "P" } + ListElement { text: "S" } + ListElement { text: "Cl" } + ListElement { text: "Ar" } + ListElement { text: "K" } + ListElement { text: "Ca" } + ListElement { text: "Sc" } + ListElement { text: "Ti" } + ListElement { text: "V" } + ListElement { text: "Cr" } + ListElement { text: "Mn" } + ListElement { text: "Fe" } + ListElement { text: "Co" } + ListElement { text: "Ni" } + ListElement { text: "Cu" } + ListElement { text: "Zn" } + ListElement { text: "Ga" } + ListElement { text: "Ge" } + ListElement { text: "As" } + ListElement { text: "Se" } + ListElement { text: "Br" } + ListElement { text: "Kr" } + ListElement { text: "Rb" } + ListElement { text: "Sr" } + ListElement { text: "Y" } + ListElement { text: "Zr" } + ListElement { text: "Nb" } + ListElement { text: "Mo" } + ListElement { text: "Tc" } + ListElement { text: "Ru" } + ListElement { text: "Rh" } + ListElement { text: "Pd" } + ListElement { text: "Ag" } + ListElement { text: "Cd" } + ListElement { text: "In" } + ListElement { text: "Sn" } + ListElement { text: "Sb" } + ListElement { text: "Te" } + ListElement { text: "I" } + ListElement { text: "Xe" } + ListElement { text: "Cs" } + ListElement { text: "Ba" } + ListElement { text: "La" } + ListElement { text: "Ce" } + ListElement { text: "Pr" } + ListElement { text: "Nd" } + ListElement { text: "Pm" } + ListElement { text: "Sm" } + ListElement { text: "Eu" } + ListElement { text: "Gd" } + ListElement { text: "Tb" } + ListElement { text: "Dy" } + ListElement { text: "Ho" } + ListElement { text: "Er" } + ListElement { text: "Tm" } + ListElement { text: "Yb" } + ListElement { text: "Lu" } + ListElement { text: "Hf" } + ListElement { text: "Ta" } + ListElement { text: "W" } + ListElement { text: "Re" } + ListElement { text: "Os" } + ListElement { text: "Ir" } + ListElement { text: "Pt" } + ListElement { text: "Au" } + ListElement { text: "Hg" } + ListElement { text: "Tl" } + ListElement { text: "Pb" } + ListElement { text: "Bi" } + ListElement { text: "Po" } + ListElement { text: "At" } + ListElement { text: "Rn" } + ListElement { text: "Fr" } + ListElement { text: "Ra" } + ListElement { text: "Ac" } + ListElement { text: "Th" } + ListElement { text: "Pa" } + ListElement { text: "U" } + ListElement { text: "Np" } + ListElement { text: "Pu" } + ListElement { text: "Am" } + ListElement { text: "Cm" } + ListElement { text: "Bk" } + ListElement { text: "Cf" } + ListElement { text: "Es" } + ListElement { text: "Fm" } + ListElement { text: "Md" } + ListElement { text: "No" } + ListElement { text: "Lr" } + ListElement { text: "Rf" } + ListElement { text: "Db" } + ListElement { text: "Sg" } + ListElement { text: "Bh" } + ListElement { text: "Hs" } + ListElement { text: "Mt" } + ListElement { text: "Ds" } + ListElement { text: "Rg" } + ListElement { text: "Cn" } + ListElement { text: "Nh" } + ListElement { text: "Fl" } + ListElement { text: "Mc" } + ListElement { text: "Lv" } + ListElement { text: "Ts" } + ListElement { text: "Og" } + ListElement { text: "Phantom" } + } +} diff --git a/src/gui/qml/nodeGraph/SpeciesDialog.qml b/src/gui/qml/nodeGraph/SpeciesDialog.qml index 3e68ceac5a..9c4b464a50 100644 --- a/src/gui/qml/nodeGraph/SpeciesDialog.qml +++ b/src/gui/qml/nodeGraph/SpeciesDialog.qml @@ -31,10 +31,10 @@ Dialog { RowLayout { Button { text: "+" - onClicked: sp.atoms.addAtom(elementField.text, xField.text, yField.text, zField.text, chargeField.text); + onClicked: sp.atoms.addAtom(elementField.currentText, xField.text, yField.text, zField.text, chargeField.text); } Text { text: "Element" } - TextField { id: elementField } + ElementComboBox { id:elementField } Text { text: "X" } TextField { id: xField } Text { text: "Y" } @@ -56,8 +56,8 @@ Dialog { delegate: Rectangle { color: "white" - implicitWidth: 100 - implicitHeight: 50 + implicitWidth: parent.parent.width / 6 - 1 + implicitHeight: 20 border.width: 1 Text { text: display From ed91049baef29d42d2a43f786bc42a519ace0543 Mon Sep 17 00:00:00 2001 From: Adam Washington Date: Fri, 14 Nov 2025 19:13:44 +0000 Subject: [PATCH 11/31] Fix bug where nodes don't export options --- src/nodes/node.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/nodes/node.cpp b/src/nodes/node.cpp index a4851f418f..35006ca7a9 100644 --- a/src/nodes/node.cpp +++ b/src/nodes/node.cpp @@ -328,6 +328,8 @@ void Node::serialise(std::string tag, SerialisedValue &target) const result["x"] = x; result["y"] = y; + fromMap(options_, "options", result); + target[tag] = result; } From 329dc89c43385442c41ed0d2d3d510608d76c6e5 Mon Sep 17 00:00:00 2001 From: Adam Washington Date: Mon, 17 Nov 2025 10:12:36 +0000 Subject: [PATCH 12/31] Start moving to immutable species --- src/classes/species.cpp | 6 ++++++ src/classes/species.h | 1 + src/gui/models/nodeGraph/parameterModel.cpp | 2 -- src/gui/qml/nodeGraph/GraphView.qml | 6 +++++- src/gui/qml/nodeGraph/ParameterDelegate.qml | 12 ------------ src/gui/qml/nodeGraph/SpeciesDialog.qml | 6 +++--- src/nodes/registry.cpp | 1 - src/nodes/species.cpp | 8 ++------ src/nodes/species.h | 4 ++-- 9 files changed, 19 insertions(+), 27 deletions(-) diff --git a/src/classes/species.cpp b/src/classes/species.cpp index bd1948a3e9..94f058513c 100644 --- a/src/classes/species.cpp +++ b/src/classes/species.cpp @@ -16,6 +16,12 @@ Species::Species(std::string name) : name_(name), attachedAtomListsGenerated_(fa naturalIsotopologue_.setParent(this); } +Species::Species(Species &species) + : name_(species.name_), version_(species.version_), atomSelectionVersion_(species.atomSelectionVersion_), + atomTypes_(species.atomTypes_) +{ +} + // Clear Data void Species::clear() { diff --git a/src/classes/species.h b/src/classes/species.h index abfed2baf6..837e70fc0e 100644 --- a/src/classes/species.h +++ b/src/classes/species.h @@ -24,6 +24,7 @@ class Species : public Serialisable { public: Species(std::string name = "Unnamed"); + Species(Species &species); ~Species() = default; // Clear Data void clear(); diff --git a/src/gui/models/nodeGraph/parameterModel.cpp b/src/gui/models/nodeGraph/parameterModel.cpp index 591b9925f7..c05d0963d0 100644 --- a/src/gui/models/nodeGraph/parameterModel.cpp +++ b/src/gui/models/nodeGraph/parameterModel.cpp @@ -46,8 +46,6 @@ QVariant ParameterModel::data(const QModelIndex &index, int role) const return QString::fromStdString(it->second->get()); if (EnumRegistry::hasEnumOption(it->second->storedDataType())) return QVariant::fromValue(it->second->getAsInt()); - if (it->second->storedDataType() == typeid(std::shared_ptr)) - return QVariant::fromValue(it->second->get>()); return QString::fromStdString("Unrepresentable"); case TYPE: if (it->second->storedDataType() == typeid(Number)) diff --git a/src/gui/qml/nodeGraph/GraphView.qml b/src/gui/qml/nodeGraph/GraphView.qml index f5f1303eca..a8bc4ee59f 100644 --- a/src/gui/qml/nodeGraph/GraphView.qml +++ b/src/gui/qml/nodeGraph/GraphView.qml @@ -117,7 +117,11 @@ Pane { MenuItem { text: "Species" - onClicked: graphRoot.rootModel.emplace_back(Math.round(ctxMenuCatcher.mouseX), Math.round(ctxMenuCatcher.mouseY), "Species", "New Species") + SpeciesDialog { + id: speciesDialog + } + + onClicked: speciesDialog.open() } } } diff --git a/src/gui/qml/nodeGraph/ParameterDelegate.qml b/src/gui/qml/nodeGraph/ParameterDelegate.qml index 6e1de46f01..f811703bba 100644 --- a/src/gui/qml/nodeGraph/ParameterDelegate.qml +++ b/src/gui/qml/nodeGraph/ParameterDelegate.qml @@ -72,18 +72,6 @@ DelegateChooser { onTextChanged: param = text } } - DelegateChoice { - roleValue: "species" - - Button { - SpeciesDialog { - id: speciesDialog - species: param - } - text: "Edit" - onClicked: speciesDialog.open() - } - } DelegateChoice { roleValue: "enum" diff --git a/src/gui/qml/nodeGraph/SpeciesDialog.qml b/src/gui/qml/nodeGraph/SpeciesDialog.qml index 9c4b464a50..e3de2f6d3b 100644 --- a/src/gui/qml/nodeGraph/SpeciesDialog.qml +++ b/src/gui/qml/nodeGraph/SpeciesDialog.qml @@ -7,14 +7,14 @@ import Dissolve Dialog { id: root - required property variant species; - standardButtons: Dialog.Ok + standardButtons: Dialog.Ok | Dialog.Cancel title: "Define Species: " + sp.name + onAccepted: console.log("Accepted Species") + SpeciesModel { id: sp - species: root.species } ColumnLayout { RowLayout { diff --git a/src/nodes/registry.cpp b/src/nodes/registry.cpp index c0014e55bc..a03e9e1899 100644 --- a/src/nodes/registry.cpp +++ b/src/nodes/registry.cpp @@ -64,7 +64,6 @@ void NodeRegistry::instantiateNodeProducers() {"Multiply", makeDerivedNode()}, {"NeutronSQ", makeDerivedNode()}, {"Number", makeDerivedNode()}, - {"Species", makeDerivedNode()}, {"SQ", makeDerivedNode()}, {"Subtract", makeDerivedNode()}, {"Vec3Assembly", makeDerivedNode()}, diff --git a/src/nodes/species.cpp b/src/nodes/species.cpp index 7ff128a532..232def2696 100644 --- a/src/nodes/species.cpp +++ b/src/nodes/species.cpp @@ -2,17 +2,13 @@ // Copyright (c) 2025 Team Dissolve and contributors #include "species.h" -#include "classes/coreData.h" #include "nodes/constants.h" -#include #include #include -SpeciesNode::SpeciesNode(Graph *parentGraph) : Node(parentGraph) +SpeciesNode::SpeciesNode(Graph *parentGraph, Species &&species) : Node(parentGraph), species_(species) { - species_ = std::make_shared(); - addOption("Data", "The data for this species", species_); - addPointerOutput("Species", "Created species", *species_); + addPointerOutput("Species", "Created species", species_); } std::string_view SpeciesNode::type() const { return "Species"; } diff --git a/src/nodes/species.h b/src/nodes/species.h index d9b5edeb07..4bafde4272 100644 --- a/src/nodes/species.h +++ b/src/nodes/species.h @@ -10,7 +10,7 @@ class SpeciesNode : public Node { public: - SpeciesNode(Graph *parentGraph); + SpeciesNode(Graph *parentGraph, Species &&species); ~SpeciesNode() override = default; /* @@ -25,7 +25,7 @@ class SpeciesNode : public Node */ private: // Species object - std::shared_ptr species_; + Species species_; // Atom Types owned by the node std::vector> atomTypes_; From 1ee2ec0b7c416fbfc1f9d76463a06ab3db9bcaee Mon Sep 17 00:00:00 2001 From: Adam Washington Date: Mon, 17 Nov 2025 11:41:29 +0000 Subject: [PATCH 13/31] Test on SpeciesModel instead of SpeciesNode --- src/classes/species.cpp | 6 --- src/classes/species.h | 1 - src/gui/models/nodeGraph/graphModel.cpp | 9 +++++ src/gui/models/nodeGraph/graphModel.h | 3 ++ src/gui/models/speciesAtomModel.cpp | 2 +- src/gui/models/speciesAtomModel.h | 4 +- src/gui/models/speciesModel.cpp | 24 +++++++----- src/gui/models/speciesModel.h | 10 ++--- src/gui/qml/nodeGraph/GraphView.qml | 1 + src/gui/qml/nodeGraph/SpeciesDialog.qml | 7 +++- src/nodes/species.cpp | 5 ++- src/nodes/species.h | 4 +- tests/gui/CMakeLists.txt | 1 + tests/gui/speciesModel.cpp | 37 ++++++++++++++++++ tests/nodes/CMakeLists.txt | 1 - tests/nodes/species.cpp | 50 ------------------------- 16 files changed, 83 insertions(+), 82 deletions(-) create mode 100644 tests/gui/speciesModel.cpp delete mode 100644 tests/nodes/species.cpp diff --git a/src/classes/species.cpp b/src/classes/species.cpp index 94f058513c..bd1948a3e9 100644 --- a/src/classes/species.cpp +++ b/src/classes/species.cpp @@ -16,12 +16,6 @@ Species::Species(std::string name) : name_(name), attachedAtomListsGenerated_(fa naturalIsotopologue_.setParent(this); } -Species::Species(Species &species) - : name_(species.name_), version_(species.version_), atomSelectionVersion_(species.atomSelectionVersion_), - atomTypes_(species.atomTypes_) -{ -} - // Clear Data void Species::clear() { diff --git a/src/classes/species.h b/src/classes/species.h index 837e70fc0e..abfed2baf6 100644 --- a/src/classes/species.h +++ b/src/classes/species.h @@ -24,7 +24,6 @@ class Species : public Serialisable { public: Species(std::string name = "Unnamed"); - Species(Species &species); ~Species() = default; // Clear Data void clear(); diff --git a/src/gui/models/nodeGraph/graphModel.cpp b/src/gui/models/nodeGraph/graphModel.cpp index 3e01eee0ee..065c903ff6 100644 --- a/src/gui/models/nodeGraph/graphModel.cpp +++ b/src/gui/models/nodeGraph/graphModel.cpp @@ -87,6 +87,15 @@ void GraphModel::descend(int index) } } +void GraphModel::addNode(std::unique_ptr node, std::string_view name) +{ + nodes_.beginInsertRows({}, graph_->nodes().size(), graph_->nodes().size() + 1); + graph_->addNode(std::move(node), name); + wrapped_.emplace_back(*graph_->nodes()[std::string(name)]); + nodes_.endInsertRows(); + graphChanged(); +} + void GraphModel::emplace_back(int x, int y, QVariant type, QVariant name) { if (!graph_) diff --git a/src/gui/models/nodeGraph/graphModel.h b/src/gui/models/nodeGraph/graphModel.h index 2d7b07ae81..34b58a15ed 100644 --- a/src/gui/models/nodeGraph/graphModel.h +++ b/src/gui/models/nodeGraph/graphModel.h @@ -50,6 +50,8 @@ class GraphModel : public QObject QString location() const; // Whether the current graph has a parent bool atRoot() const; + // Add a pre-created node + void addNode(std::unique_ptr node, std::string_view name); protected: // The abstract data model for the nodes @@ -91,6 +93,7 @@ class GraphModel : public QObject // Provide relative coordinates for an output on a node void addOutput(int nodeIndex, QString paramName, double x, double y); + // Add a new node at a specific position void emplace_back(int x, int y, QVariant type, QVariant name); diff --git a/src/gui/models/speciesAtomModel.cpp b/src/gui/models/speciesAtomModel.cpp index e151633866..a087f3edc3 100644 --- a/src/gui/models/speciesAtomModel.cpp +++ b/src/gui/models/speciesAtomModel.cpp @@ -4,7 +4,7 @@ SpeciesAtomModel::SpeciesAtomModel() {} -void SpeciesAtomModel::setSpecies(std::shared_ptr species) { species_ = species; } +void SpeciesAtomModel::setSpecies(Species *species) { species_ = species; } void SpeciesAtomModel::addAtom(QString element, double x, double y, double z, double charge) { diff --git a/src/gui/models/speciesAtomModel.h b/src/gui/models/speciesAtomModel.h index d4e955b59f..f9540c54ac 100644 --- a/src/gui/models/speciesAtomModel.h +++ b/src/gui/models/speciesAtomModel.h @@ -13,7 +13,7 @@ class SpeciesAtomModel : public QAbstractTableModel Q_OBJECT private: - std::shared_ptr species_; + Species *species_; Q_SIGNALS: void atomTypeChanged(); @@ -24,7 +24,7 @@ class SpeciesAtomModel : public QAbstractTableModel public: SpeciesAtomModel(); - void setSpecies(std::shared_ptr species); + void setSpecies(Species *species); int rowCount(const QModelIndex &parent = QModelIndex()) const override; diff --git a/src/gui/models/speciesModel.cpp b/src/gui/models/speciesModel.cpp index d0cb822648..74f8d349c6 100644 --- a/src/gui/models/speciesModel.cpp +++ b/src/gui/models/speciesModel.cpp @@ -2,21 +2,16 @@ // Copyright (c) 2025 Team Dissolve and contributors #include "gui/models/speciesModel.h" +#include "gui/models/nodeGraph/graphModel.h" +#include "nodes/species.h" #include "speciesAtomModel.h" #include -SpeciesModel::SpeciesModel() { species_ = std::make_shared(); } - -// Access source Species data -std::shared_ptr SpeciesModel::species() { return species_; } - -// Set source Species data -void SpeciesModel::setSpecies(std::shared_ptr species) +SpeciesModel::SpeciesModel() { - species_ = species; + species_ = std::make_unique(); + atoms_.setSpecies(species_.get()); bonds_.setBonds(species_->bonds()); - atoms_.setSpecies(species_); - Q_EMIT(speciesChanged()); } QString SpeciesModel::name() { return QString::fromStdString(std::string(species_->name())); } @@ -33,6 +28,15 @@ SpeciesBondModel *SpeciesModel::bonds() { return &bonds_; } // Atom information SpeciesAtomModel *SpeciesModel::atoms() { return &atoms_; } +void SpeciesModel::create(QVariant graphModel) +{ + auto model = graphModel.value(); + model->addNode(std::move(std::make_unique(model->graph(), std::move(species_))), species_->name()); + + // Create a new species for the next call + species_ = std::make_unique(); +} + // const Species *SpeciesModel::rawData(const QModelIndex &index) const // { // assert(species_); diff --git a/src/gui/models/speciesModel.h b/src/gui/models/speciesModel.h index ef64140c8c..6d5810580a 100644 --- a/src/gui/models/speciesModel.h +++ b/src/gui/models/speciesModel.h @@ -16,14 +16,13 @@ class SpeciesModel : public QObject { Q_OBJECT // The Species being modelled - Q_PROPERTY(std::shared_ptr species READ species WRITE setSpecies NOTIFY speciesChanged) Q_PROPERTY(SpeciesAtomModel *atoms READ atoms NOTIFY speciesChanged) Q_PROPERTY(SpeciesBondModel *bonds READ bonds NOTIFY speciesChanged) Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) private: // Source Species data - std::shared_ptr species_; + std::unique_ptr species_; // Atom Model SpeciesAtomModel atoms_; // Bond Model @@ -44,10 +43,6 @@ class SpeciesModel : public QObject public: SpeciesModel(); - // Set source Species data - void setSpecies(std::shared_ptr species); - // Set source Species data - std::shared_ptr species(); // Species name QString name(); // Species name @@ -66,4 +61,7 @@ class SpeciesModel : public QObject void speciesChanged(); // The name has changed void nameChanged(); + + public Q_SLOTS: + void create(QVariant graphModel); }; diff --git a/src/gui/qml/nodeGraph/GraphView.qml b/src/gui/qml/nodeGraph/GraphView.qml index a8bc4ee59f..2e46e30681 100644 --- a/src/gui/qml/nodeGraph/GraphView.qml +++ b/src/gui/qml/nodeGraph/GraphView.qml @@ -119,6 +119,7 @@ Pane { SpeciesDialog { id: speciesDialog + graphModel: graphRoot.rootModel } onClicked: speciesDialog.open() diff --git a/src/gui/qml/nodeGraph/SpeciesDialog.qml b/src/gui/qml/nodeGraph/SpeciesDialog.qml index e3de2f6d3b..066c496e17 100644 --- a/src/gui/qml/nodeGraph/SpeciesDialog.qml +++ b/src/gui/qml/nodeGraph/SpeciesDialog.qml @@ -8,14 +8,19 @@ import Dissolve Dialog { id: root + required property variant graphModel; + standardButtons: Dialog.Ok | Dialog.Cancel title: "Define Species: " + sp.name - onAccepted: console.log("Accepted Species") + onAccepted: { + sp.create(graphModel); + } SpeciesModel { id: sp } + ColumnLayout { RowLayout { Text {text: "Name"} diff --git a/src/nodes/species.cpp b/src/nodes/species.cpp index 232def2696..b7edd4d10c 100644 --- a/src/nodes/species.cpp +++ b/src/nodes/species.cpp @@ -6,9 +6,10 @@ #include #include -SpeciesNode::SpeciesNode(Graph *parentGraph, Species &&species) : Node(parentGraph), species_(species) +SpeciesNode::SpeciesNode(Graph *parentGraph, std::unique_ptr &&species) + : Node(parentGraph), species_(std::move(species)) { - addPointerOutput("Species", "Created species", species_); + addPointerOutput("Species", "Created species", *species_); } std::string_view SpeciesNode::type() const { return "Species"; } diff --git a/src/nodes/species.h b/src/nodes/species.h index 4bafde4272..873aa96ff1 100644 --- a/src/nodes/species.h +++ b/src/nodes/species.h @@ -10,7 +10,7 @@ class SpeciesNode : public Node { public: - SpeciesNode(Graph *parentGraph, Species &&species); + SpeciesNode(Graph *parentGraph, std::unique_ptr &&species); ~SpeciesNode() override = default; /* @@ -25,7 +25,7 @@ class SpeciesNode : public Node */ private: // Species object - Species species_; + std::unique_ptr species_; // Atom Types owned by the node std::vector> atomTypes_; diff --git a/tests/gui/CMakeLists.txt b/tests/gui/CMakeLists.txt index 15d953151f..70ddeeba8b 100644 --- a/tests/gui/CMakeLists.txt +++ b/tests/gui/CMakeLists.txt @@ -7,3 +7,4 @@ dissolve_add_test(SRC masterTerms.cpp GUI) dissolve_add_test(SRC procedure.cpp GUI) dissolve_add_test(SRC modifyCharges.cpp GUI) dissolve_add_test(SRC xmlForcefield.cpp GUI) +dissolve_add_test(SRC speciesModel.cpp GUI) diff --git a/tests/gui/speciesModel.cpp b/tests/gui/speciesModel.cpp new file mode 100644 index 0000000000..160137acd6 --- /dev/null +++ b/tests/gui/speciesModel.cpp @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright (c) 2025 Team Dissolve and contributors + +#include "gui/models/speciesModel.h" +#include "data/elements.h" +#include "gui/models/nodeGraph/graphModel.h" +#include + +namespace UnitTest +{ +TEST(SpeciesModel, Basic) +{ + SpeciesModel model; + model.setName("Water"); + model.atoms()->addAtom("O", 0.156743, -0.152502, 0.317676, -0.82); + model.atoms()->addAtom("H", -0.257130, 0.637822, 0.198948, 0.41); + model.atoms()->addAtom("H", 0.100387, -0.485320, -0.516624, 0.41); + + Graph graph(nullptr); + GraphModel graphModel; + graphModel.setGraph(&graph); + model.create(QVariant::fromValue(&graphModel)); + + ASSERT_EQ(graph.nodes().size(), 3); + + auto &node = graph.nodes().at("Water"); + + ASSERT_NE(node, nullptr); + + auto species = node->findOutput("Species")->get(); + + ASSERT_NE(species, nullptr); + EXPECT_EQ(species->name(), "Water"); + EXPECT_EQ(species->atom(0).Z(), Elements::Element::O); + EXPECT_EQ(species->atom(1).Z(), Elements::Element::H); +} +} // namespace UnitTest diff --git a/tests/nodes/CMakeLists.txt b/tests/nodes/CMakeLists.txt index f9b8f26f42..3a77d1d055 100644 --- a/tests/nodes/CMakeLists.txt +++ b/tests/nodes/CMakeLists.txt @@ -4,4 +4,3 @@ dissolve_add_test(SRC graph_argon.cpp) dissolve_add_test(SRC number.cpp) dissolve_add_test(SRC parameters.cpp) dissolve_add_test(SRC subGraph.cpp) -dissolve_add_test(SRC species.cpp) diff --git a/tests/nodes/species.cpp b/tests/nodes/species.cpp deleted file mode 100644 index 2471e42e1d..0000000000 --- a/tests/nodes/species.cpp +++ /dev/null @@ -1,50 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2025 Team Dissolve and contributors - -#include "nodes/species.h" -#include "nodes/constants.h" -#include "nodes/dissolve.h" -#include - -namespace UnitTest -{ -class SpeciesNodeTest : public ::testing::Test -{ - public: - SpeciesNodeTest() : dissolve_(coreData_), root_(dissolve_) {} - - protected: - // We need a CoreData and Dissolve definition to properly - // instantiate DissolveGraph at present. - CoreData coreData_; - Dissolve dissolve_; - DissolveGraph root_; -}; - -TEST_F(SpeciesNodeTest, Creation) -{ - auto s = dynamic_cast(root_.createNode("Species", "s")); - ASSERT_EQ(s->name(), "s"); - auto option = s->findOption("Data"); - ASSERT_NE(option, nullptr); - - auto species = option->get>(); - species->addAtom(Elements::O, {0.156743, -0.152502, 0.317676}, -0.82); - species->addAtom(Elements::H, {-0.257130, 0.637822, 0.198948}, 0.41); - species->addAtom(Elements::H, {0.100387, -0.485320, -0.516624}, 0.41); - species->addBond(0, 1); - species->addBond(0, 2); - species->addAngle(1, 0, 2); - - ASSERT_EQ(s->run(), NodeConstants::ProcessResult::Unchanged); - auto result = s->findOutput("Species")->get(); - - ASSERT_EQ(result->atoms().size(), 3); - ASSERT_EQ(result->atom(0).charge(), -0.82); - ASSERT_EQ(result->atom(1).r().x, -0.257130); - - ASSERT_EQ(result->bonds().size(), 2); - ASSERT_EQ(result->angles().size(), 1); -} - -}; // namespace UnitTest From 66146317a7bc571de98b6c08c13d2a6f69a46f91 Mon Sep 17 00:00:00 2001 From: Adam Washington Date: Mon, 17 Nov 2025 17:06:22 +0000 Subject: [PATCH 14/31] Switch to shared_ptr --- src/nodes/parameter.h | 1 + src/nodes/species.cpp | 4 +++- src/nodes/species.h | 4 ++-- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/nodes/parameter.h b/src/nodes/parameter.h index d532fe24de..0284e89b4e 100644 --- a/src/nodes/parameter.h +++ b/src/nodes/parameter.h @@ -5,6 +5,7 @@ #include "base/enumOptions.h" #include "base/serialiser.h" +#include "classes/coreData.h" #include "math/data1D.h" #include "math/function1D.h" #include "nodes/number.h" diff --git a/src/nodes/species.cpp b/src/nodes/species.cpp index b7edd4d10c..83c4425cc3 100644 --- a/src/nodes/species.cpp +++ b/src/nodes/species.cpp @@ -3,12 +3,14 @@ #include "species.h" #include "nodes/constants.h" +#include #include #include -SpeciesNode::SpeciesNode(Graph *parentGraph, std::unique_ptr &&species) +SpeciesNode::SpeciesNode(Graph *parentGraph, std::shared_ptr &&species) : Node(parentGraph), species_(std::move(species)) { + addOption>("Species", "Created Species", species_); addPointerOutput("Species", "Created species", *species_); } diff --git a/src/nodes/species.h b/src/nodes/species.h index 873aa96ff1..9e2a5d3746 100644 --- a/src/nodes/species.h +++ b/src/nodes/species.h @@ -10,7 +10,7 @@ class SpeciesNode : public Node { public: - SpeciesNode(Graph *parentGraph, std::unique_ptr &&species); + SpeciesNode(Graph *parentGraph, std::shared_ptr &&species); ~SpeciesNode() override = default; /* @@ -25,7 +25,7 @@ class SpeciesNode : public Node */ private: // Species object - std::unique_ptr species_; + std::shared_ptr species_; // Atom Types owned by the node std::vector> atomTypes_; From 7eab1d6c1bee8ed51eecef23ed19260003d767c1 Mon Sep 17 00:00:00 2001 From: Adam Washington Date: Tue, 18 Nov 2025 10:07:30 +0000 Subject: [PATCH 15/31] Ensure that species is serialised --- example.toml | 61 +++++++++++++++++++++++++++++++++++++ src/classes/species.cpp | 4 +-- src/classes/speciesAtom.cpp | 4 ++- 3 files changed, 65 insertions(+), 4 deletions(-) create mode 100644 example.toml diff --git a/example.toml b/example.toml new file mode 100644 index 0000000000..080abcdb34 --- /dev/null +++ b/example.toml @@ -0,0 +1,61 @@ +version = "1.8.0" + +[pairPotentials] +range = 15.0 +delta = 0.005 +autoChargeSource = true +coulombTruncation = "Shifted" +shortRangeTruncation = "Shifted" +includeCoulomb = true + +[graph] +name = "Root" +type = "Dissolve" +x = 0 +y = 0 + +[graph.nodes] + +[graph.nodes.Water] +name = "Water" +type = "Species" +x = 0 +y = 0 + +[graph.nodes.Water.options] + +[graph.nodes.Water.options.Species] + +[graph.nodes.Water.options.Species.data] +name = "Water" + +[[graph.nodes.Water.options.Species.data.atoms]] +index = 1 +z = "O" +r = [ +1.0, +2.0, +3.0, +] +charge = -0.82 +[[graph.nodes.Water.options.Species.data.atoms]] +index = 2 +z = "H" +r = [ +4.0, +25.0, +nan, +] +charge = 0.42 +[[graph.nodes.Water.options.Species.data.atoms]] +index = 3 +z = "H" +r = [ +7.0, +8.0, +9.0, +] +charge = 0.42 + + + diff --git a/src/classes/species.cpp b/src/classes/species.cpp index bd1948a3e9..a2c3ebeedf 100644 --- a/src/classes/species.cpp +++ b/src/classes/species.cpp @@ -208,10 +208,8 @@ int Species::version() const { return version_; } // Express as a serialisable value void Species::serialise(std::string tag, SerialisedValue &target) const { - if (forcefield_ == nullptr && atoms_.empty() && bonds_.empty() && angles_.empty() && torsions_.empty() && - isotopologues_.empty() && sites_.empty()) - return; auto &result = target[tag]; + result["name"] = name_; if (forcefield_ != nullptr) result["forcefield"] = forcefield_->name().data(); diff --git a/src/classes/speciesAtom.cpp b/src/classes/speciesAtom.cpp index bf6a94e5e0..088711d7dd 100644 --- a/src/classes/speciesAtom.cpp +++ b/src/classes/speciesAtom.cpp @@ -486,7 +486,9 @@ int SpeciesAtom::guessOxidationState(const SpeciesAtom *i) // Express as a serialisable value void SpeciesAtom::serialise(std::string tag, SerialisedValue &target) const { - target[tag] = {{"index", userIndex()}, {"z", Z_}, {"r", r_}, {"charge", charge_}, {"type", atomType_->name().data()}}; + target[tag] = {{"index", userIndex()}, {"z", Z_}, {"r", r_}, {"charge", charge_}}; + if (atomType_) + target[tag]["type"] = atomType_->name().data(); } void SpeciesAtom::deserialise(const SerialisedValue &node, CoreData &coreData) { From 43a8bbf97c9d6132ba13b03b75a0a580767ea713 Mon Sep 17 00:00:00 2001 From: Adam Washington Date: Tue, 18 Nov 2025 16:16:05 +0000 Subject: [PATCH 16/31] Statr validating atom input --- src/gui/qml/nodeGraph/SpeciesDialog.qml | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/gui/qml/nodeGraph/SpeciesDialog.qml b/src/gui/qml/nodeGraph/SpeciesDialog.qml index 066c496e17..6941742ac7 100644 --- a/src/gui/qml/nodeGraph/SpeciesDialog.qml +++ b/src/gui/qml/nodeGraph/SpeciesDialog.qml @@ -36,18 +36,31 @@ Dialog { RowLayout { Button { text: "+" + enabled: xField.text != "" && yField.text!= "" && zField.text!= "" && chargeField.text != ""; onClicked: sp.atoms.addAtom(elementField.currentText, xField.text, yField.text, zField.text, chargeField.text); } Text { text: "Element" } ElementComboBox { id:elementField } Text { text: "X" } - TextField { id: xField } + TextField { + id: xField + validator: DoubleValidator {} + } Text { text: "Y" } - TextField { id: yField } + TextField { + id: yField + validator: DoubleValidator {} + } Text { text: "Z" } - TextField { id: zField } + TextField { + id: zField + validator: DoubleValidator {} + } Text { text: "Charge" } - TextField { id: chargeField } + TextField { + id: chargeField + validator: DoubleValidator {} + } } TableView { Layout.fillHeight: true From 265990e46ab397090a6204c99e0f3197c032e435 Mon Sep 17 00:00:00 2001 From: Adam Washington Date: Tue, 18 Nov 2025 16:29:41 +0000 Subject: [PATCH 17/31] Start adding bond info to species dialog --- example.toml | 61 ------------------------- src/gui/models/speciesBondModel.h | 2 + src/gui/models/speciesModel.cpp | 7 +++ src/gui/models/speciesModel.h | 1 + src/gui/qml/nodeGraph/SpeciesDialog.qml | 45 ++++++++++++++---- 5 files changed, 46 insertions(+), 70 deletions(-) delete mode 100644 example.toml diff --git a/example.toml b/example.toml deleted file mode 100644 index 080abcdb34..0000000000 --- a/example.toml +++ /dev/null @@ -1,61 +0,0 @@ -version = "1.8.0" - -[pairPotentials] -range = 15.0 -delta = 0.005 -autoChargeSource = true -coulombTruncation = "Shifted" -shortRangeTruncation = "Shifted" -includeCoulomb = true - -[graph] -name = "Root" -type = "Dissolve" -x = 0 -y = 0 - -[graph.nodes] - -[graph.nodes.Water] -name = "Water" -type = "Species" -x = 0 -y = 0 - -[graph.nodes.Water.options] - -[graph.nodes.Water.options.Species] - -[graph.nodes.Water.options.Species.data] -name = "Water" - -[[graph.nodes.Water.options.Species.data.atoms]] -index = 1 -z = "O" -r = [ -1.0, -2.0, -3.0, -] -charge = -0.82 -[[graph.nodes.Water.options.Species.data.atoms]] -index = 2 -z = "H" -r = [ -4.0, -25.0, -nan, -] -charge = 0.42 -[[graph.nodes.Water.options.Species.data.atoms]] -index = 3 -z = "H" -r = [ -7.0, -8.0, -9.0, -] -charge = 0.42 - - - diff --git a/src/gui/models/speciesBondModel.h b/src/gui/models/speciesBondModel.h index 812e30d18f..a4dade9b5d 100644 --- a/src/gui/models/speciesBondModel.h +++ b/src/gui/models/speciesBondModel.h @@ -34,4 +34,6 @@ class SpeciesBondModel : public QAbstractTableModel QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; Qt::ItemFlags flags(const QModelIndex &index) const override; bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; + + friend class SpeciesModel; }; diff --git a/src/gui/models/speciesModel.cpp b/src/gui/models/speciesModel.cpp index 74f8d349c6..7db441872d 100644 --- a/src/gui/models/speciesModel.cpp +++ b/src/gui/models/speciesModel.cpp @@ -37,6 +37,13 @@ void SpeciesModel::create(QVariant graphModel) species_ = std::make_unique(); } +void SpeciesModel::addBond(int i, int j) +{ + bonds_.beginInsertRows({}, species_->nBonds(), species_->nBonds() + 1); + species_->addBond(i, j); + bonds_.endInsertRows(); +} + // const Species *SpeciesModel::rawData(const QModelIndex &index) const // { // assert(species_); diff --git a/src/gui/models/speciesModel.h b/src/gui/models/speciesModel.h index 6d5810580a..8a70b132bf 100644 --- a/src/gui/models/speciesModel.h +++ b/src/gui/models/speciesModel.h @@ -64,4 +64,5 @@ class SpeciesModel : public QObject public Q_SLOTS: void create(QVariant graphModel); + void addBond(int i, int j); }; diff --git a/src/gui/qml/nodeGraph/SpeciesDialog.qml b/src/gui/qml/nodeGraph/SpeciesDialog.qml index 6941742ac7..e565c15b44 100644 --- a/src/gui/qml/nodeGraph/SpeciesDialog.qml +++ b/src/gui/qml/nodeGraph/SpeciesDialog.qml @@ -31,7 +31,7 @@ Dialog { } GroupBox { id: atomBox - title: "Atoms (" + sp.atoms.rowCount() + ")" + title: "Atoms" ColumnLayout { RowLayout { Button { @@ -88,14 +88,41 @@ Dialog { GridLayout { columns: 2 GroupBox { - title: "Bonds (" + sp.bonds.rowCount() + ")" - TableView { - model: sp.atoms - delegate: Rectangle { - implicitWidth: 100 - implicitHeight: 50 - Text { - text: display + title: "Bonds" + ColumnLayout { + RowLayout { + Button { + text: "+" + enabled: bondI.text != "" && bondJ.text!= ""; + onClicked: sp.addBond(bondI.currentText, bondJ.currentText); + } + Text { text: "I" } + TextField { + id: bondI + validator: IntValidator {} + } + Text { text: "J" } + TextField { + id: bondJ + validator: IntValidator {} + } + } + TableView { + Layout.fillHeight: true + Layout.fillWidth: true + implicitHeight: 400 + model: sp.bonds + delegate: Rectangle { + implicitWidth: 100 + implicitHeight: 50 + Text { + text: display + visible: currentColumn != 2 + } + TextField { + text: display + visible: currentColumn == 2 + } } } } From e402383cfd2140a5768037941d1d501b726317db Mon Sep 17 00:00:00 2001 From: Adam Washington Date: Tue, 18 Nov 2025 16:52:48 +0000 Subject: [PATCH 18/31] Add Species Node icon --- src/gui/icons/nodes/Species.svg | 85 +++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 src/gui/icons/nodes/Species.svg diff --git a/src/gui/icons/nodes/Species.svg b/src/gui/icons/nodes/Species.svg new file mode 100644 index 0000000000..60a57fc1fa --- /dev/null +++ b/src/gui/icons/nodes/Species.svg @@ -0,0 +1,85 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + From 53d5e7e2b75ed35d4756bdfdada709d69cca323c Mon Sep 17 00:00:00 2001 From: Adam Washington Date: Tue, 18 Nov 2025 16:52:48 +0000 Subject: [PATCH 19/31] Better finish on Bond model --- src/gui/models/speciesModel.cpp | 2 +- src/gui/qml/nodeGraph/SpeciesDialog.qml | 59 +++++++++++++++++++------ 2 files changed, 46 insertions(+), 15 deletions(-) diff --git a/src/gui/models/speciesModel.cpp b/src/gui/models/speciesModel.cpp index 7db441872d..c1ca086ce6 100644 --- a/src/gui/models/speciesModel.cpp +++ b/src/gui/models/speciesModel.cpp @@ -40,7 +40,7 @@ void SpeciesModel::create(QVariant graphModel) void SpeciesModel::addBond(int i, int j) { bonds_.beginInsertRows({}, species_->nBonds(), species_->nBonds() + 1); - species_->addBond(i, j); + species_->addBond(i - 1, j - 1); bonds_.endInsertRows(); } diff --git a/src/gui/qml/nodeGraph/SpeciesDialog.qml b/src/gui/qml/nodeGraph/SpeciesDialog.qml index e565c15b44..f7cde19966 100644 --- a/src/gui/qml/nodeGraph/SpeciesDialog.qml +++ b/src/gui/qml/nodeGraph/SpeciesDialog.qml @@ -65,7 +65,7 @@ Dialog { TableView { Layout.fillHeight: true Layout.fillWidth: true - implicitHeight: 400 + implicitHeight: 200 clip: true columnSpacing: 1 rowSpacing: 1 @@ -94,7 +94,7 @@ Dialog { Button { text: "+" enabled: bondI.text != "" && bondJ.text!= ""; - onClicked: sp.addBond(bondI.currentText, bondJ.currentText); + onClicked: sp.addBond(bondI.text, bondJ.text); } Text { text: "I" } TextField { @@ -110,25 +110,56 @@ Dialog { TableView { Layout.fillHeight: true Layout.fillWidth: true - implicitHeight: 400 + implicitHeight: 200 + implicitWidth: bondI.width*4 model: sp.bonds - delegate: Rectangle { - implicitWidth: 100 - implicitHeight: 50 - Text { - text: display - visible: currentColumn != 2 - } - TextField { - text: display - visible: currentColumn == 2 - } + delegate: TextField { + text: display + width: 10 + onTextChanged: edit = text } } } } GroupBox { title: "Angles" + ColumnLayout { + RowLayout { + Button { + text: "+" + enabled: angleI.text != "" && angleJ.text!= ""; + onClicked: sp.addAngle(angleI.text, angleJ.text, angleK); + } + Text { text: "I" } + TextField { + id: angleI + validator: IntValidator {} + } + Text { text: "J" } + TextField { + id: angleJ + validator: IntValidator {} + } + Text { text: "K" } + TextField { + id: angleK + validator: IntValidator {} + } + } + TableView { + Layout.fillHeight: true + Layout.fillWidth: true + implicitHeight: 200 + implicitWidth: parent.parent.width/2 + model: sp.angles + delegate: TextField { + text: display + color: "#00FFFF" + width: 20 + onTextChanged: edit = text + } + } + } } GroupBox { title: "Torsions" From a63fb4033fc74564068ec78cd952c438718155f3 Mon Sep 17 00:00:00 2001 From: Adam Washington Date: Wed, 19 Nov 2025 13:40:31 +0000 Subject: [PATCH 20/31] Move add button to end of tab order --- src/gui/qml/nodeGraph/SpeciesDialog.qml | 30 ++++++++++++------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/gui/qml/nodeGraph/SpeciesDialog.qml b/src/gui/qml/nodeGraph/SpeciesDialog.qml index f7cde19966..aca307320e 100644 --- a/src/gui/qml/nodeGraph/SpeciesDialog.qml +++ b/src/gui/qml/nodeGraph/SpeciesDialog.qml @@ -34,11 +34,6 @@ Dialog { title: "Atoms" ColumnLayout { RowLayout { - Button { - text: "+" - enabled: xField.text != "" && yField.text!= "" && zField.text!= "" && chargeField.text != ""; - onClicked: sp.atoms.addAtom(elementField.currentText, xField.text, yField.text, zField.text, chargeField.text); - } Text { text: "Element" } ElementComboBox { id:elementField } Text { text: "X" } @@ -61,6 +56,11 @@ Dialog { id: chargeField validator: DoubleValidator {} } + Button { + text: "+" + enabled: xField.text != "" && yField.text!= "" && zField.text!= "" && chargeField.text != ""; + onClicked: sp.atoms.addAtom(elementField.currentText, xField.text, yField.text, zField.text, chargeField.text); + } } TableView { Layout.fillHeight: true @@ -91,11 +91,6 @@ Dialog { title: "Bonds" ColumnLayout { RowLayout { - Button { - text: "+" - enabled: bondI.text != "" && bondJ.text!= ""; - onClicked: sp.addBond(bondI.text, bondJ.text); - } Text { text: "I" } TextField { id: bondI @@ -106,6 +101,11 @@ Dialog { id: bondJ validator: IntValidator {} } + Button { + text: "+" + enabled: bondI.text != "" && bondJ.text!= ""; + onClicked: sp.addBond(bondI.text, bondJ.text); + } } TableView { Layout.fillHeight: true @@ -125,11 +125,6 @@ Dialog { title: "Angles" ColumnLayout { RowLayout { - Button { - text: "+" - enabled: angleI.text != "" && angleJ.text!= ""; - onClicked: sp.addAngle(angleI.text, angleJ.text, angleK); - } Text { text: "I" } TextField { id: angleI @@ -145,6 +140,11 @@ Dialog { id: angleK validator: IntValidator {} } + Button { + text: "+" + enabled: angleI.text != "" && angleJ.text!= ""; + onClicked: sp.addAngle(angleI.text, angleJ.text, angleK); + } } TableView { Layout.fillHeight: true From c3fa0230eedff2a9fe1e1b034a253c284ff14a2e Mon Sep 17 00:00:00 2001 From: Adam Washington Date: Wed, 19 Nov 2025 13:40:31 +0000 Subject: [PATCH 21/31] Better implicit widths --- src/gui/qml/nodeGraph/SpeciesDialog.qml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/gui/qml/nodeGraph/SpeciesDialog.qml b/src/gui/qml/nodeGraph/SpeciesDialog.qml index aca307320e..ac6719f423 100644 --- a/src/gui/qml/nodeGraph/SpeciesDialog.qml +++ b/src/gui/qml/nodeGraph/SpeciesDialog.qml @@ -66,6 +66,7 @@ Dialog { Layout.fillHeight: true Layout.fillWidth: true implicitHeight: 200 + implicitWidth: zField.width * sp.atoms.columnCount() clip: true columnSpacing: 1 rowSpacing: 1 @@ -111,7 +112,7 @@ Dialog { Layout.fillHeight: true Layout.fillWidth: true implicitHeight: 200 - implicitWidth: bondI.width*4 + implicitWidth: bondI.width*sp.bonds.columnCount() model: sp.bonds delegate: TextField { text: display @@ -150,7 +151,7 @@ Dialog { Layout.fillHeight: true Layout.fillWidth: true implicitHeight: 200 - implicitWidth: parent.parent.width/2 + implicitWidth: angleI.width*sp.angles.columnCount() model: sp.angles delegate: TextField { text: display From d57abf1fc0792f9b90a49d135f0cf341f6286aa2 Mon Sep 17 00:00:00 2001 From: Adam Washington Date: Wed, 19 Nov 2025 13:40:31 +0000 Subject: [PATCH 22/31] Add angle to model --- src/gui/models/speciesAngleModel.cpp | 42 ++++++++++--------------- src/gui/models/speciesAngleModel.h | 8 +++-- src/gui/models/speciesModel.cpp | 14 +++++++++ src/gui/models/speciesModel.h | 15 +++++++++ src/gui/qml/nodeGraph/SpeciesDialog.qml | 7 ++--- 5 files changed, 54 insertions(+), 32 deletions(-) diff --git a/src/gui/models/speciesAngleModel.cpp b/src/gui/models/speciesAngleModel.cpp index 9d1f026bc5..c277e72782 100644 --- a/src/gui/models/speciesAngleModel.cpp +++ b/src/gui/models/speciesAngleModel.cpp @@ -2,23 +2,26 @@ // Copyright (c) 2025 Team Dissolve and contributors #include "gui/models/speciesAngleModel.h" -#include "classes/coreData.h" -SpeciesAngleModel::SpeciesAngleModel(std::vector &angles, const CoreData &coreData) - : angles_(angles), coreData_(coreData) +SpeciesAngleModel::SpeciesAngleModel() : angles_(nullptr) {} + +void SpeciesAngleModel::reset() { + beginResetModel(); + endResetModel(); } -void SpeciesAngleModel::reset() +void SpeciesAngleModel::setAngles(std::vector &angles) { beginResetModel(); + angles_ = &angles; endResetModel(); } int SpeciesAngleModel::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent); - return angles_.size(); + return angles_->size(); } int SpeciesAngleModel::columnCount(const QModelIndex &parent) const @@ -32,7 +35,7 @@ QVariant SpeciesAngleModel::data(const QModelIndex &index, int role) const if (role == Qt::ToolTipRole) return headerData(index.column(), Qt::Horizontal, Qt::DisplayRole); - auto &angle = angles_[index.row()]; + auto angle = angles_->at(index.row()); if (role == Qt::UserRole) return QVariant::fromValue(&angle); @@ -83,14 +86,14 @@ Qt::ItemFlags SpeciesAngleModel::flags(const QModelIndex &index) const { if (index.column() <= DataType::IndexK) return Qt::ItemIsSelectable | Qt::ItemIsEnabled; - if (index.column() > DataType::Form && angles_[index.row()].masterTerm()) + if (index.column() > DataType::Form && angles_->at(index.row()).masterTerm()) return Qt::ItemIsSelectable | Qt::ItemIsEnabled; return Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled; } bool SpeciesAngleModel::setData(const QModelIndex &index, const QVariant &value, int role) { - auto &angle = angles_[index.row()]; + auto &angle = angles_->at(index.row()); switch (index.column()) { case (DataType::IndexI): @@ -98,26 +101,15 @@ bool SpeciesAngleModel::setData(const QModelIndex &index, const QVariant &value, case (DataType::IndexK): return false; case (DataType::Form): - if (value.toString().at(0) == '@') + try { - auto master = coreData_.getMasterAngle(value.toString().toStdString()); - if (master) - angle.setMasterTerm(&master->get()); - else - return false; + auto af = AngleFunctions::forms().enumeration(value.toString().toStdString()); + angle.detachFromMasterTerm(); + angle.setInteractionForm(af); } - else + catch (std::runtime_error &e) { - try - { - auto af = AngleFunctions::forms().enumeration(value.toString().toStdString()); - angle.detachFromMasterTerm(); - angle.setInteractionForm(af); - } - catch (std::runtime_error &e) - { - return false; - } + return false; } break; case (DataType::Parameters): diff --git a/src/gui/models/speciesAngleModel.h b/src/gui/models/speciesAngleModel.h index ace7b86214..dd25ba5547 100644 --- a/src/gui/models/speciesAngleModel.h +++ b/src/gui/models/speciesAngleModel.h @@ -26,11 +26,11 @@ class SpeciesAngleModel : public QAbstractTableModel }; private: - std::vector &angles_; - const CoreData &coreData_; + std::vector *angles_; public: - SpeciesAngleModel(std::vector &angles, const CoreData &coreData); + SpeciesAngleModel(); + void setAngles(std::vector &angles); void reset(); int rowCount(const QModelIndex &parent = QModelIndex()) const override; int columnCount(const QModelIndex &parent = QModelIndex()) const override; @@ -38,4 +38,6 @@ class SpeciesAngleModel : public QAbstractTableModel QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; Qt::ItemFlags flags(const QModelIndex &index) const override; bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; + + friend class SpeciesModel; }; diff --git a/src/gui/models/speciesModel.cpp b/src/gui/models/speciesModel.cpp index c1ca086ce6..4b29bc8be4 100644 --- a/src/gui/models/speciesModel.cpp +++ b/src/gui/models/speciesModel.cpp @@ -12,6 +12,7 @@ SpeciesModel::SpeciesModel() species_ = std::make_unique(); atoms_.setSpecies(species_.get()); bonds_.setBonds(species_->bonds()); + angles_.setAngles(species_->angles()); } QString SpeciesModel::name() { return QString::fromStdString(std::string(species_->name())); } @@ -25,6 +26,9 @@ void SpeciesModel::setName(QString name) // Bond information SpeciesBondModel *SpeciesModel::bonds() { return &bonds_; } +// Angle information +SpeciesAngleModel *SpeciesModel::angles() { return &angles_; } + // Atom information SpeciesAtomModel *SpeciesModel::atoms() { return &atoms_; } @@ -44,6 +48,16 @@ void SpeciesModel::addBond(int i, int j) bonds_.endInsertRows(); } +void SpeciesModel::addAngle(int i, int j, int k) +{ + std::cout << "Adding angle: " << i << "\t" << j << "\t" << k << std::endl; + angles_.beginInsertRows({}, species_->nAngles(), species_->nAngles() + 1); + species_->addAngle(i - 1, j - 1, k - 1); + angles_.endInsertRows(); + std::cout << "nAngles: " << species_->nAngles() << std::endl; + std::cout << "Rows: " << angles_.rowCount() << std::endl; +} + // const Species *SpeciesModel::rawData(const QModelIndex &index) const // { // assert(species_); diff --git a/src/gui/models/speciesModel.h b/src/gui/models/speciesModel.h index 8a70b132bf..21021319b6 100644 --- a/src/gui/models/speciesModel.h +++ b/src/gui/models/speciesModel.h @@ -4,8 +4,11 @@ #pragma once #include "classes/species.h" +#include "gui/models/speciesAngleModel.h" #include "gui/models/speciesAtomModel.h" #include "gui/models/speciesBondModel.h" +#include "gui/models/speciesImproperModel.h" +#include "gui/models/speciesTorsionModel.h" #include #include @@ -18,6 +21,7 @@ class SpeciesModel : public QObject // The Species being modelled Q_PROPERTY(SpeciesAtomModel *atoms READ atoms NOTIFY speciesChanged) Q_PROPERTY(SpeciesBondModel *bonds READ bonds NOTIFY speciesChanged) + Q_PROPERTY(SpeciesAngleModel *angles READ angles NOTIFY speciesChanged) Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) private: @@ -27,6 +31,12 @@ class SpeciesModel : public QObject SpeciesAtomModel atoms_; // Bond Model SpeciesBondModel bonds_; + // Angle Model + SpeciesAngleModel angles_; + // // Torsion Model + // SpeciesTorsionModel torsions_; + // // Improper Model + // SpeciesImproperModel impropers_; // Return object represented by specified model index const Species *rawData(const QModelIndex &index) const; @@ -51,6 +61,8 @@ class SpeciesModel : public QObject SpeciesAtomModel *atoms(); // Bond information SpeciesBondModel *bonds(); + // Angle information + SpeciesAngleModel *angles(); // Set vector containing checked items void setCheckStateData(std::vector &checkedItemsVector); // Refresh model data @@ -65,4 +77,7 @@ class SpeciesModel : public QObject public Q_SLOTS: void create(QVariant graphModel); void addBond(int i, int j); + void addAngle(int i, int j, int k); + // void addTorsion(int i, int j, int k, int l); + // void addImproper(int i, int j, int k, int l); }; diff --git a/src/gui/qml/nodeGraph/SpeciesDialog.qml b/src/gui/qml/nodeGraph/SpeciesDialog.qml index ac6719f423..8476e40121 100644 --- a/src/gui/qml/nodeGraph/SpeciesDialog.qml +++ b/src/gui/qml/nodeGraph/SpeciesDialog.qml @@ -143,8 +143,8 @@ Dialog { } Button { text: "+" - enabled: angleI.text != "" && angleJ.text!= ""; - onClicked: sp.addAngle(angleI.text, angleJ.text, angleK); + enabled: angleI.text != "" && angleJ.text!= "" && angleK.text != ""; + onClicked: sp.addAngle(angleI.text, angleJ.text, angleK.text); } } TableView { @@ -155,8 +155,7 @@ Dialog { model: sp.angles delegate: TextField { text: display - color: "#00FFFF" - width: 20 + width: 10 onTextChanged: edit = text } } From 48b3ae1515b331f4696d58653e29b130cd78a71d Mon Sep 17 00:00:00 2001 From: Adam Washington Date: Wed, 19 Nov 2025 16:05:41 +0000 Subject: [PATCH 23/31] Add torsions to species model --- src/gui/models/speciesModel.cpp | 14 +++++++-- src/gui/models/speciesModel.h | 9 ++++-- src/gui/models/speciesTorsionModel.cpp | 42 +++++++++++-------------- src/gui/models/speciesTorsionModel.h | 8 +++-- src/gui/qml/nodeGraph/SpeciesDialog.qml | 41 ++++++++++++++++++++++++ 5 files changed, 81 insertions(+), 33 deletions(-) diff --git a/src/gui/models/speciesModel.cpp b/src/gui/models/speciesModel.cpp index 4b29bc8be4..2ad595d755 100644 --- a/src/gui/models/speciesModel.cpp +++ b/src/gui/models/speciesModel.cpp @@ -13,6 +13,7 @@ SpeciesModel::SpeciesModel() atoms_.setSpecies(species_.get()); bonds_.setBonds(species_->bonds()); angles_.setAngles(species_->angles()); + torsions_.setTorsions(species_->torsions()); } QString SpeciesModel::name() { return QString::fromStdString(std::string(species_->name())); } @@ -29,6 +30,9 @@ SpeciesBondModel *SpeciesModel::bonds() { return &bonds_; } // Angle information SpeciesAngleModel *SpeciesModel::angles() { return &angles_; } +// Torsion information +SpeciesTorsionModel *SpeciesModel::torsions() { return &torsions_; } + // Atom information SpeciesAtomModel *SpeciesModel::atoms() { return &atoms_; } @@ -50,12 +54,16 @@ void SpeciesModel::addBond(int i, int j) void SpeciesModel::addAngle(int i, int j, int k) { - std::cout << "Adding angle: " << i << "\t" << j << "\t" << k << std::endl; angles_.beginInsertRows({}, species_->nAngles(), species_->nAngles() + 1); species_->addAngle(i - 1, j - 1, k - 1); angles_.endInsertRows(); - std::cout << "nAngles: " << species_->nAngles() << std::endl; - std::cout << "Rows: " << angles_.rowCount() << std::endl; +} + +void SpeciesModel::addTorsion(int i, int j, int k, int l) +{ + torsions_.beginInsertRows({}, species_->nTorsions(), species_->nTorsions() + 1); + species_->addTorsion(i - 1, j - 1, k - 1, l - 1); + torsions_.endInsertRows(); } // const Species *SpeciesModel::rawData(const QModelIndex &index) const diff --git a/src/gui/models/speciesModel.h b/src/gui/models/speciesModel.h index 21021319b6..e2f3e19da1 100644 --- a/src/gui/models/speciesModel.h +++ b/src/gui/models/speciesModel.h @@ -22,6 +22,7 @@ class SpeciesModel : public QObject Q_PROPERTY(SpeciesAtomModel *atoms READ atoms NOTIFY speciesChanged) Q_PROPERTY(SpeciesBondModel *bonds READ bonds NOTIFY speciesChanged) Q_PROPERTY(SpeciesAngleModel *angles READ angles NOTIFY speciesChanged) + Q_PROPERTY(SpeciesTorsionModel *torsions READ torsions NOTIFY speciesChanged) Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) private: @@ -33,8 +34,8 @@ class SpeciesModel : public QObject SpeciesBondModel bonds_; // Angle Model SpeciesAngleModel angles_; - // // Torsion Model - // SpeciesTorsionModel torsions_; + // Torsion Model + SpeciesTorsionModel torsions_; // // Improper Model // SpeciesImproperModel impropers_; // Return object represented by specified model index @@ -63,6 +64,8 @@ class SpeciesModel : public QObject SpeciesBondModel *bonds(); // Angle information SpeciesAngleModel *angles(); + // Torsion information + SpeciesTorsionModel *torsions(); // Set vector containing checked items void setCheckStateData(std::vector &checkedItemsVector); // Refresh model data @@ -78,6 +81,6 @@ class SpeciesModel : public QObject void create(QVariant graphModel); void addBond(int i, int j); void addAngle(int i, int j, int k); - // void addTorsion(int i, int j, int k, int l); + void addTorsion(int i, int j, int k, int l); // void addImproper(int i, int j, int k, int l); }; diff --git a/src/gui/models/speciesTorsionModel.cpp b/src/gui/models/speciesTorsionModel.cpp index d1ff57f3c7..a24c576aaf 100644 --- a/src/gui/models/speciesTorsionModel.cpp +++ b/src/gui/models/speciesTorsionModel.cpp @@ -4,21 +4,25 @@ #include "gui/models/speciesTorsionModel.h" #include "classes/coreData.h" -SpeciesTorsionModel::SpeciesTorsionModel(std::vector &torsions, const CoreData &coreData) - : torsions_(torsions), coreData_(coreData) +SpeciesTorsionModel::SpeciesTorsionModel() : torsions_(nullptr) {} + +void SpeciesTorsionModel::reset() { + beginResetModel(); + endResetModel(); } -void SpeciesTorsionModel::reset() +void SpeciesTorsionModel::setTorsions(std::vector &torsions) { beginResetModel(); + torsions_ = &torsions; endResetModel(); } int SpeciesTorsionModel::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent); - return torsions_.size(); + return torsions_->size(); } int SpeciesTorsionModel::columnCount(const QModelIndex &parent) const @@ -32,7 +36,7 @@ QVariant SpeciesTorsionModel::data(const QModelIndex &index, int role) const if (role == Qt::ToolTipRole) return headerData(index.column(), Qt::Horizontal, Qt::DisplayRole); - auto &torsion = torsions_[index.row()]; + auto &torsion = torsions_->at(index.row()); if (role == Qt::UserRole) return QVariant::fromValue(&torsion); @@ -97,14 +101,14 @@ Qt::ItemFlags SpeciesTorsionModel::flags(const QModelIndex &index) const { if (index.column() <= DataType::IndexL) return Qt::ItemIsSelectable | Qt::ItemIsEnabled; - if (index.column() > DataType::Form && torsions_[index.row()].masterTerm()) + if (index.column() > DataType::Form && torsions_->at(index.row()).masterTerm()) return Qt::ItemIsSelectable | Qt::ItemIsEnabled; return Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled; } bool SpeciesTorsionModel::setData(const QModelIndex &index, const QVariant &value, int role) { - auto &torsion = torsions_[index.row()]; + auto &torsion = torsions_->at(index.row()); switch (index.column()) { case (DataType::IndexI): @@ -113,27 +117,17 @@ bool SpeciesTorsionModel::setData(const QModelIndex &index, const QVariant &valu case (DataType::IndexL): return false; case (DataType::Form): - if (value.toString().at(0) == '@') + try { - auto master = coreData_.getMasterTorsion(value.toString().toStdString()); - if (master) - torsion.setMasterTerm(&master->get()); - else - return false; + auto tf = TorsionFunctions::forms().enumeration(value.toString().toStdString()); + torsion.detachFromMasterTerm(); + torsion.setInteractionForm(tf); } - else + catch (std::runtime_error &e) { - try - { - auto tf = TorsionFunctions::forms().enumeration(value.toString().toStdString()); - torsion.detachFromMasterTerm(); - torsion.setInteractionForm(tf); - } - catch (std::runtime_error &e) - { - return false; - } + return false; } + break; case (DataType::Parameters): if (!torsion.setInteractionParameters(value.toString().toStdString())) diff --git a/src/gui/models/speciesTorsionModel.h b/src/gui/models/speciesTorsionModel.h index f3aef26bd2..cfbb0dfaf1 100644 --- a/src/gui/models/speciesTorsionModel.h +++ b/src/gui/models/speciesTorsionModel.h @@ -30,11 +30,11 @@ class SpeciesTorsionModel : public QAbstractTableModel }; private: - std::vector &torsions_; - const CoreData &coreData_; + std::vector *torsions_; public: - SpeciesTorsionModel(std::vector &torsions, const CoreData &coreData); + SpeciesTorsionModel(); + void setTorsions(std::vector &torsions); void reset(); int rowCount(const QModelIndex &parent = QModelIndex()) const override; int columnCount(const QModelIndex &parent = QModelIndex()) const override; @@ -42,4 +42,6 @@ class SpeciesTorsionModel : public QAbstractTableModel QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; Qt::ItemFlags flags(const QModelIndex &index) const override; bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; + + friend class SpeciesModel; }; diff --git a/src/gui/qml/nodeGraph/SpeciesDialog.qml b/src/gui/qml/nodeGraph/SpeciesDialog.qml index 8476e40121..c38c3889f9 100644 --- a/src/gui/qml/nodeGraph/SpeciesDialog.qml +++ b/src/gui/qml/nodeGraph/SpeciesDialog.qml @@ -163,6 +163,47 @@ Dialog { } GroupBox { title: "Torsions" + ColumnLayout { + RowLayout { + Text { text: "I" } + TextField { + id: torsionI + validator: IntValidator {} + } + Text { text: "J" } + TextField { + id: torsionJ + validator: IntValidator {} + } + Text { text: "K" } + TextField { + id: torsionK + validator: IntValidator {} + } + Text { text: "L" } + TextField { + id: torsionL + validator: IntValidator {} + } + Button { + text: "+" + enabled: torsionI.text != "" && torsionJ.text!= "" && torsionK.text != "" && torsionL.text != ""; + onClicked: sp.addTorsion(torsionI.text, torsionJ.text, torsionK.text, torsionL.text); + } + } + TableView { + Layout.fillHeight: true + Layout.fillWidth: true + implicitHeight: 200 + implicitWidth: torsionI.width*sp.torsions.columnCount() + model: sp.torsions + delegate: TextField { + text: display + width: 10 + onTextChanged: edit = text + } + } + } } GroupBox { title: "Impropers" From 0dc8bc3ed953d9ae584466fe479437958aebd7e0 Mon Sep 17 00:00:00 2001 From: Adam Washington Date: Wed, 19 Nov 2025 16:28:45 +0000 Subject: [PATCH 24/31] Add impropers to species model --- src/gui/models/speciesImproperModel.cpp | 41 ++++++++++-------------- src/gui/models/speciesImproperModel.h | 9 +++--- src/gui/models/speciesModel.cpp | 11 +++++++ src/gui/models/speciesModel.h | 9 ++++-- src/gui/models/speciesTorsionModel.h | 2 +- src/gui/qml/nodeGraph/SpeciesDialog.qml | 42 +++++++++++++++++++++++++ 6 files changed, 82 insertions(+), 32 deletions(-) diff --git a/src/gui/models/speciesImproperModel.cpp b/src/gui/models/speciesImproperModel.cpp index e7d992590d..8222a11913 100644 --- a/src/gui/models/speciesImproperModel.cpp +++ b/src/gui/models/speciesImproperModel.cpp @@ -4,21 +4,25 @@ #include "gui/models/speciesImproperModel.h" #include "classes/coreData.h" -SpeciesImproperModel::SpeciesImproperModel(std::vector &impropers, const CoreData &coreData) - : impropers_(impropers), coreData_(coreData) +SpeciesImproperModel::SpeciesImproperModel() : impropers_(nullptr) {} + +void SpeciesImproperModel::reset() { + beginResetModel(); + endResetModel(); } -void SpeciesImproperModel::reset() +void SpeciesImproperModel::setImpropers(std::vector &impropers) { beginResetModel(); + impropers_ = &impropers; endResetModel(); } int SpeciesImproperModel::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent); - return impropers_.size(); + return impropers_->size(); } int SpeciesImproperModel::columnCount(const QModelIndex &parent) const @@ -32,7 +36,7 @@ QVariant SpeciesImproperModel::data(const QModelIndex &index, int role) const if (role == Qt::ToolTipRole) return headerData(index.column(), Qt::Horizontal, Qt::DisplayRole); - auto &improper = impropers_[index.row()]; + auto &improper = impropers_->at(index.row()); if (role == Qt::UserRole) return QVariant::fromValue(&improper); @@ -87,14 +91,14 @@ Qt::ItemFlags SpeciesImproperModel::flags(const QModelIndex &index) const { if (index.column() <= DataType::IndexL) return Qt::ItemIsSelectable | Qt::ItemIsEnabled; - if (index.column() > DataType::Form && impropers_[index.row()].masterTerm()) + if (index.column() > DataType::Form && impropers_->at(index.row()).masterTerm()) return Qt::ItemIsSelectable | Qt::ItemIsEnabled; return Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled; } bool SpeciesImproperModel::setData(const QModelIndex &index, const QVariant &value, int role) { - auto &improper = impropers_[index.row()]; + auto &improper = impropers_->at(index.row()); switch (index.column()) { case (DataType::IndexI): @@ -103,26 +107,15 @@ bool SpeciesImproperModel::setData(const QModelIndex &index, const QVariant &val case (DataType::IndexL): return false; case (DataType::Form): - if (value.toString().at(0) == '@') + try { - auto master = coreData_.getMasterImproper(value.toString().toStdString()); - if (master) - improper.setMasterTerm(&master->get()); - else - return false; + auto tf = TorsionFunctions::forms().enumeration(value.toString().toStdString()); + improper.detachFromMasterTerm(); + improper.setInteractionForm(tf); } - else + catch (std::runtime_error &e) { - try - { - auto tf = TorsionFunctions::forms().enumeration(value.toString().toStdString()); - improper.detachFromMasterTerm(); - improper.setInteractionForm(tf); - } - catch (std::runtime_error &e) - { - return false; - } + return false; } break; case (DataType::Parameters): diff --git a/src/gui/models/speciesImproperModel.h b/src/gui/models/speciesImproperModel.h index 982c0c28f9..ce6feea6f4 100644 --- a/src/gui/models/speciesImproperModel.h +++ b/src/gui/models/speciesImproperModel.h @@ -4,7 +4,6 @@ #pragma once #include "classes/speciesImproper.h" -#include "data/ff/improperTerm.h" #include #include #include @@ -29,16 +28,18 @@ class SpeciesImproperModel : public QAbstractTableModel }; private: - std::vector &impropers_; - const CoreData &coreData_; + std::vector *impropers_; public: - SpeciesImproperModel(std::vector &impropers, const CoreData &coreData); + SpeciesImproperModel(); void reset(); + void setImpropers(std::vector &impropers); int rowCount(const QModelIndex &parent = QModelIndex()) const override; int columnCount(const QModelIndex &parent = QModelIndex()) const override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; Qt::ItemFlags flags(const QModelIndex &index) const override; bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; + + friend class SpeciesModel; }; diff --git a/src/gui/models/speciesModel.cpp b/src/gui/models/speciesModel.cpp index 2ad595d755..dc2d17f2e4 100644 --- a/src/gui/models/speciesModel.cpp +++ b/src/gui/models/speciesModel.cpp @@ -14,6 +14,7 @@ SpeciesModel::SpeciesModel() bonds_.setBonds(species_->bonds()); angles_.setAngles(species_->angles()); torsions_.setTorsions(species_->torsions()); + impropers_.setImpropers(species_->impropers()); } QString SpeciesModel::name() { return QString::fromStdString(std::string(species_->name())); } @@ -33,6 +34,9 @@ SpeciesAngleModel *SpeciesModel::angles() { return &angles_; } // Torsion information SpeciesTorsionModel *SpeciesModel::torsions() { return &torsions_; } +// Improper information +SpeciesImproperModel *SpeciesModel::impropers() { return &impropers_; } + // Atom information SpeciesAtomModel *SpeciesModel::atoms() { return &atoms_; } @@ -66,6 +70,13 @@ void SpeciesModel::addTorsion(int i, int j, int k, int l) torsions_.endInsertRows(); } +void SpeciesModel::addImproper(int i, int j, int k, int l) +{ + impropers_.beginInsertRows({}, species_->nImpropers(), species_->nImpropers() + 1); + species_->addImproper(i - 1, j - 1, k - 1, l - 1); + impropers_.endInsertRows(); +} + // const Species *SpeciesModel::rawData(const QModelIndex &index) const // { // assert(species_); diff --git a/src/gui/models/speciesModel.h b/src/gui/models/speciesModel.h index e2f3e19da1..b2573db310 100644 --- a/src/gui/models/speciesModel.h +++ b/src/gui/models/speciesModel.h @@ -23,6 +23,7 @@ class SpeciesModel : public QObject Q_PROPERTY(SpeciesBondModel *bonds READ bonds NOTIFY speciesChanged) Q_PROPERTY(SpeciesAngleModel *angles READ angles NOTIFY speciesChanged) Q_PROPERTY(SpeciesTorsionModel *torsions READ torsions NOTIFY speciesChanged) + Q_PROPERTY(SpeciesImproperModel *impropers READ impropers NOTIFY speciesChanged) Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) private: @@ -36,8 +37,8 @@ class SpeciesModel : public QObject SpeciesAngleModel angles_; // Torsion Model SpeciesTorsionModel torsions_; - // // Improper Model - // SpeciesImproperModel impropers_; + // Improper Model + SpeciesImproperModel impropers_; // Return object represented by specified model index const Species *rawData(const QModelIndex &index) const; @@ -66,6 +67,8 @@ class SpeciesModel : public QObject SpeciesAngleModel *angles(); // Torsion information SpeciesTorsionModel *torsions(); + // Improper information + SpeciesImproperModel *impropers(); // Set vector containing checked items void setCheckStateData(std::vector &checkedItemsVector); // Refresh model data @@ -82,5 +85,5 @@ class SpeciesModel : public QObject void addBond(int i, int j); void addAngle(int i, int j, int k); void addTorsion(int i, int j, int k, int l); - // void addImproper(int i, int j, int k, int l); + void addImproper(int i, int j, int k, int l); }; diff --git a/src/gui/models/speciesTorsionModel.h b/src/gui/models/speciesTorsionModel.h index cfbb0dfaf1..0389c6fc2f 100644 --- a/src/gui/models/speciesTorsionModel.h +++ b/src/gui/models/speciesTorsionModel.h @@ -34,8 +34,8 @@ class SpeciesTorsionModel : public QAbstractTableModel public: SpeciesTorsionModel(); - void setTorsions(std::vector &torsions); void reset(); + void setTorsions(std::vector &torsions); int rowCount(const QModelIndex &parent = QModelIndex()) const override; int columnCount(const QModelIndex &parent = QModelIndex()) const override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; diff --git a/src/gui/qml/nodeGraph/SpeciesDialog.qml b/src/gui/qml/nodeGraph/SpeciesDialog.qml index c38c3889f9..6350e9675b 100644 --- a/src/gui/qml/nodeGraph/SpeciesDialog.qml +++ b/src/gui/qml/nodeGraph/SpeciesDialog.qml @@ -205,8 +205,50 @@ Dialog { } } } + GroupBox { title: "Impropers" + ColumnLayout { + RowLayout { + Text { text: "I" } + TextField { + id: improperI + validator: IntValidator {} + } + Text { text: "J" } + TextField { + id: improperJ + validator: IntValidator {} + } + Text { text: "K" } + TextField { + id: improperK + validator: IntValidator {} + } + Text { text: "L" } + TextField { + id: improperL + validator: IntValidator {} + } + Button { + text: "+" + enabled: improperI.text != "" && improperJ.text!= "" && improperK.text != "" && improperL.text != ""; + onClicked: sp.addImproper(improperI.text, improperJ.text, improperK.text, improperL.text); + } + } + TableView { + Layout.fillHeight: true + Layout.fillWidth: true + implicitHeight: 200 + implicitWidth: improperI.width*sp.impropers.columnCount() + model: sp.impropers + delegate: TextField { + text: display + width: 10 + onTextChanged: edit = text + } + } + } } } } From f00551ed19e94a360574603afa68eabc0214818d Mon Sep 17 00:00:00 2001 From: Adam Washington Date: Wed, 19 Nov 2025 16:57:23 +0000 Subject: [PATCH 25/31] Include atom type in species --- src/classes/atomType.h | 3 ++- src/gui/models/speciesAtomModel.cpp | 16 +++++++++++++++- src/gui/qml/nodeGraph/SpeciesDialog.qml | 10 +++------- 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/classes/atomType.h b/src/classes/atomType.h index bb77b8c4a5..4c07d97a09 100644 --- a/src/classes/atomType.h +++ b/src/classes/atomType.h @@ -9,10 +9,11 @@ #include "classes/shortRangeFunctions.h" #include "data/elements.h" #include +#include #include // AtomType Definition -class AtomType : public Serialisable<> +class AtomType : public Serialisable<>, public std::enable_shared_from_this { public: AtomType(Elements::Element Z = Elements::Unknown); diff --git a/src/gui/models/speciesAtomModel.cpp b/src/gui/models/speciesAtomModel.cpp index a087f3edc3..011374e852 100644 --- a/src/gui/models/speciesAtomModel.cpp +++ b/src/gui/models/speciesAtomModel.cpp @@ -1,6 +1,7 @@ #include "gui/models/speciesAtomModel.h" #include "classes/species.h" #include "data/elements.h" +#include SpeciesAtomModel::SpeciesAtomModel() {} @@ -107,7 +108,20 @@ bool SpeciesAtomModel::setData(const QModelIndex &index, const QVariant &value, case 0: return false; case 1: - return false; + { + auto population = species_->atomTypePopulations().vector(); + auto name = value.toString().toStdString(); + auto it = std::find_if(population.begin(), population.end(), [&name](auto &x) { return x.first->name() == name; }); + if (it == population.end()) + { + auto at = species_->addAtomType(item.Z()); + at->setName(value.toString().toStdString()); + item.setAtomType(at); + } + else + item.setAtomType(std::const_pointer_cast(it->first->shared_from_this())); + } + break; // FIXME: we don't have atom types yet // { // auto atomType = coreData_.findAtomType(value.toString().toStdString()); diff --git a/src/gui/qml/nodeGraph/SpeciesDialog.qml b/src/gui/qml/nodeGraph/SpeciesDialog.qml index 6350e9675b..447854d23f 100644 --- a/src/gui/qml/nodeGraph/SpeciesDialog.qml +++ b/src/gui/qml/nodeGraph/SpeciesDialog.qml @@ -73,15 +73,11 @@ Dialog { model: sp.atoms - delegate: Rectangle { - color: "white" + delegate: TextField { + text: display implicitWidth: parent.parent.width / 6 - 1 implicitHeight: 20 - border.width: 1 - Text { - text: display - anchors.centerIn: parent - } + onTextChanged: edit = text } } } From cd504169b7d72fdb346e6b24fbfb3ace1d24ae12 Mon Sep 17 00:00:00 2001 From: Adam Washington Date: Wed, 19 Nov 2025 16:57:23 +0000 Subject: [PATCH 26/31] Fix loading species --- src/nodes/graph.cpp | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/nodes/graph.cpp b/src/nodes/graph.cpp index ff1c37fb09..b942369e0a 100644 --- a/src/nodes/graph.cpp +++ b/src/nodes/graph.cpp @@ -6,6 +6,7 @@ #include "nodes/inputs.h" #include "nodes/outputs.h" #include "nodes/registry.h" +#include "species.h" Graph::Graph(Graph *parentGraph) : Node(parentGraph) { @@ -266,9 +267,22 @@ void Graph::deserialise(const SerialisedValue &node) [this](const auto name, const auto &value) { std::string nodeType = toml::find(value, "type"); - auto child = createNode(nodeType, name); - - child->deserialise(value); + if (nodeType == "Species") + { + // Species cannot be default constructed and requires species handling. + auto species = std::make_shared(); + CoreData coreData; + species->deserialise(value.at("options").at("Species").at("data"), coreData); + species->setName(name); + std::unique_ptr spNode = std::make_unique(this, std::move(species)); + addNode(std::move(spNode), name); + } + else + { + auto child = createNode(nodeType, name); + + child->deserialise(value); + } }); toVector(node, "edges", [this](const auto &value) { addEdge(toml::get(value)); }); } From 181b12f20f75f460336fbde44885ced436812963 Mon Sep 17 00:00:00 2001 From: Adam Washington Date: Thu, 20 Nov 2025 14:15:09 +0000 Subject: [PATCH 27/31] More comprehensive testing of SpeciesModel --- src/gui/models/speciesAngleModel.h | 1 + src/gui/models/speciesBondModel.h | 1 + src/gui/models/speciesImproperModel.h | 1 + src/gui/models/speciesTorsionModel.h | 1 + tests/gui/speciesModel.cpp | 24 ++++++++++++++++++++++++ 5 files changed, 28 insertions(+) diff --git a/src/gui/models/speciesAngleModel.h b/src/gui/models/speciesAngleModel.h index dd25ba5547..b679c9b51b 100644 --- a/src/gui/models/speciesAngleModel.h +++ b/src/gui/models/speciesAngleModel.h @@ -14,6 +14,7 @@ class SpeciesAngleModel : public QAbstractTableModel { Q_OBJECT + public: // Enumerated column-to-data relationships enum DataType { diff --git a/src/gui/models/speciesBondModel.h b/src/gui/models/speciesBondModel.h index a4dade9b5d..b407a161ef 100644 --- a/src/gui/models/speciesBondModel.h +++ b/src/gui/models/speciesBondModel.h @@ -11,6 +11,7 @@ class SpeciesBondModel : public QAbstractTableModel { Q_OBJECT + public: // Enumerated column-to-data relationships enum DataType { diff --git a/src/gui/models/speciesImproperModel.h b/src/gui/models/speciesImproperModel.h index ce6feea6f4..05a03751cf 100644 --- a/src/gui/models/speciesImproperModel.h +++ b/src/gui/models/speciesImproperModel.h @@ -15,6 +15,7 @@ class SpeciesImproperModel : public QAbstractTableModel { Q_OBJECT + public: // Enumerated column-to-data relationships enum DataType { diff --git a/src/gui/models/speciesTorsionModel.h b/src/gui/models/speciesTorsionModel.h index 0389c6fc2f..f3b051e40d 100644 --- a/src/gui/models/speciesTorsionModel.h +++ b/src/gui/models/speciesTorsionModel.h @@ -15,6 +15,7 @@ class SpeciesTorsionModel : public QAbstractTableModel { Q_OBJECT + public: // Enumerated column-to-data relationships enum DataType { diff --git a/tests/gui/speciesModel.cpp b/tests/gui/speciesModel.cpp index 160137acd6..df63a32bde 100644 --- a/tests/gui/speciesModel.cpp +++ b/tests/gui/speciesModel.cpp @@ -2,6 +2,7 @@ // Copyright (c) 2025 Team Dissolve and contributors #include "gui/models/speciesModel.h" +#include "classes/bondFunctions.h" #include "data/elements.h" #include "gui/models/nodeGraph/graphModel.h" #include @@ -10,12 +11,30 @@ namespace UnitTest { TEST(SpeciesModel, Basic) { + + // Stage 1: Simulate GUI interactions to create species SpeciesModel model; model.setName("Water"); model.atoms()->addAtom("O", 0.156743, -0.152502, 0.317676, -0.82); model.atoms()->addAtom("H", -0.257130, 0.637822, 0.198948, 0.41); model.atoms()->addAtom("H", 0.100387, -0.485320, -0.516624, 0.41); + model.addBond(1, 2); + auto bonds = model.bonds(); + EXPECT_FALSE(bonds->setData(bonds->index(0, SpeciesBondModel::DataType::Form), "Harmonix")); + EXPECT_TRUE(bonds->setData(bonds->index(0, SpeciesBondModel::DataType::Form), "Harmonic")); + EXPECT_FALSE(bonds->setData(bonds->index(0, SpeciesBondModel::DataType::Parameters), "k=")); + EXPECT_TRUE(bonds->setData(bonds->index(0, SpeciesBondModel::DataType::Parameters), "k=4431.53 eq=1.012")); + model.addBond(1, 3); + EXPECT_TRUE(bonds->setData(bonds->index(1, SpeciesBondModel::DataType::Form), "Harmonic")); + EXPECT_TRUE(bonds->setData(bonds->index(1, SpeciesBondModel::DataType::Parameters), "k=4431.53 eq=1.012")); + model.addAngle(2, 1, 3); + + auto angles = model.angles(); + EXPECT_TRUE(angles->setData(angles->index(0, SpeciesAngleModel::DataType::Form), "Harmonic")); + EXPECT_TRUE(angles->setData(angles->index(0, SpeciesAngleModel::DataType::Parameters), "k=317.5656 eq=113.24")); + + // Stage 2: Extract species from node Graph graph(nullptr); GraphModel graphModel; graphModel.setGraph(&graph); @@ -29,9 +48,14 @@ TEST(SpeciesModel, Basic) auto species = node->findOutput("Species")->get(); + // Stage 3: Confirm that species was created correctly ASSERT_NE(species, nullptr); EXPECT_EQ(species->name(), "Water"); EXPECT_EQ(species->atom(0).Z(), Elements::Element::O); EXPECT_EQ(species->atom(1).Z(), Elements::Element::H); + + EXPECT_EQ(species->bonds()[0].interactionForm(), BondFunctions::Form::Harmonic); + EXPECT_EQ(species->bonds()[1].interactionParameters()[1], 1.012); + EXPECT_EQ(species->angles()[0].interactionForm(), AngleFunctions::Form::Harmonic); } } // namespace UnitTest From 05b2ba70f638a6d3319a47163ebdeab108968f2b Mon Sep 17 00:00:00 2001 From: Adam Washington Date: Thu, 20 Nov 2025 14:40:41 +0000 Subject: [PATCH 28/31] Fix formatting --- src/gui/models/nodeGraph/graphModel.h | 1 - src/gui/qml/nodeGraph/ElementComboBox.qml | 479 +++++++++++++----- src/gui/qml/nodeGraph/GraphView.qml | 9 +- src/gui/qml/nodeGraph/SpeciesDialog.qml | 216 +++++--- .../SimulationDataManager.qml | 3 +- 5 files changed, 520 insertions(+), 188 deletions(-) diff --git a/src/gui/models/nodeGraph/graphModel.h b/src/gui/models/nodeGraph/graphModel.h index 34b58a15ed..e0225d6d09 100644 --- a/src/gui/models/nodeGraph/graphModel.h +++ b/src/gui/models/nodeGraph/graphModel.h @@ -93,7 +93,6 @@ class GraphModel : public QObject // Provide relative coordinates for an output on a node void addOutput(int nodeIndex, QString paramName, double x, double y); - // Add a new node at a specific position void emplace_back(int x, int y, QVariant type, QVariant name); diff --git a/src/gui/qml/nodeGraph/ElementComboBox.qml b/src/gui/qml/nodeGraph/ElementComboBox.qml index ea926d9ca5..5214e5eede 100644 --- a/src/gui/qml/nodeGraph/ElementComboBox.qml +++ b/src/gui/qml/nodeGraph/ElementComboBox.qml @@ -2,129 +2,368 @@ import QtQuick import QtQuick.Controls import Qt.labs.qmlmodels - ComboBox { editable: true + model: ListModel { id: model - ListElement { text: "H" } - ListElement { text: "He" } - ListElement { text: "Li" } - ListElement { text: "Be" } - ListElement { text: "B" } - ListElement { text: "C" } - ListElement { text: "N" } - ListElement { text: "O" } - ListElement { text: "F" } - ListElement { text: "Ne" } - ListElement { text: "Na" } - ListElement { text: "Mg" } - ListElement { text: "Al" } - ListElement { text: "Si" } - ListElement { text: "P" } - ListElement { text: "S" } - ListElement { text: "Cl" } - ListElement { text: "Ar" } - ListElement { text: "K" } - ListElement { text: "Ca" } - ListElement { text: "Sc" } - ListElement { text: "Ti" } - ListElement { text: "V" } - ListElement { text: "Cr" } - ListElement { text: "Mn" } - ListElement { text: "Fe" } - ListElement { text: "Co" } - ListElement { text: "Ni" } - ListElement { text: "Cu" } - ListElement { text: "Zn" } - ListElement { text: "Ga" } - ListElement { text: "Ge" } - ListElement { text: "As" } - ListElement { text: "Se" } - ListElement { text: "Br" } - ListElement { text: "Kr" } - ListElement { text: "Rb" } - ListElement { text: "Sr" } - ListElement { text: "Y" } - ListElement { text: "Zr" } - ListElement { text: "Nb" } - ListElement { text: "Mo" } - ListElement { text: "Tc" } - ListElement { text: "Ru" } - ListElement { text: "Rh" } - ListElement { text: "Pd" } - ListElement { text: "Ag" } - ListElement { text: "Cd" } - ListElement { text: "In" } - ListElement { text: "Sn" } - ListElement { text: "Sb" } - ListElement { text: "Te" } - ListElement { text: "I" } - ListElement { text: "Xe" } - ListElement { text: "Cs" } - ListElement { text: "Ba" } - ListElement { text: "La" } - ListElement { text: "Ce" } - ListElement { text: "Pr" } - ListElement { text: "Nd" } - ListElement { text: "Pm" } - ListElement { text: "Sm" } - ListElement { text: "Eu" } - ListElement { text: "Gd" } - ListElement { text: "Tb" } - ListElement { text: "Dy" } - ListElement { text: "Ho" } - ListElement { text: "Er" } - ListElement { text: "Tm" } - ListElement { text: "Yb" } - ListElement { text: "Lu" } - ListElement { text: "Hf" } - ListElement { text: "Ta" } - ListElement { text: "W" } - ListElement { text: "Re" } - ListElement { text: "Os" } - ListElement { text: "Ir" } - ListElement { text: "Pt" } - ListElement { text: "Au" } - ListElement { text: "Hg" } - ListElement { text: "Tl" } - ListElement { text: "Pb" } - ListElement { text: "Bi" } - ListElement { text: "Po" } - ListElement { text: "At" } - ListElement { text: "Rn" } - ListElement { text: "Fr" } - ListElement { text: "Ra" } - ListElement { text: "Ac" } - ListElement { text: "Th" } - ListElement { text: "Pa" } - ListElement { text: "U" } - ListElement { text: "Np" } - ListElement { text: "Pu" } - ListElement { text: "Am" } - ListElement { text: "Cm" } - ListElement { text: "Bk" } - ListElement { text: "Cf" } - ListElement { text: "Es" } - ListElement { text: "Fm" } - ListElement { text: "Md" } - ListElement { text: "No" } - ListElement { text: "Lr" } - ListElement { text: "Rf" } - ListElement { text: "Db" } - ListElement { text: "Sg" } - ListElement { text: "Bh" } - ListElement { text: "Hs" } - ListElement { text: "Mt" } - ListElement { text: "Ds" } - ListElement { text: "Rg" } - ListElement { text: "Cn" } - ListElement { text: "Nh" } - ListElement { text: "Fl" } - ListElement { text: "Mc" } - ListElement { text: "Lv" } - ListElement { text: "Ts" } - ListElement { text: "Og" } - ListElement { text: "Phantom" } + + ListElement { + text: "H" + } + ListElement { + text: "He" + } + ListElement { + text: "Li" + } + ListElement { + text: "Be" + } + ListElement { + text: "B" + } + ListElement { + text: "C" + } + ListElement { + text: "N" + } + ListElement { + text: "O" + } + ListElement { + text: "F" + } + ListElement { + text: "Ne" + } + ListElement { + text: "Na" + } + ListElement { + text: "Mg" + } + ListElement { + text: "Al" + } + ListElement { + text: "Si" + } + ListElement { + text: "P" + } + ListElement { + text: "S" + } + ListElement { + text: "Cl" + } + ListElement { + text: "Ar" + } + ListElement { + text: "K" + } + ListElement { + text: "Ca" + } + ListElement { + text: "Sc" + } + ListElement { + text: "Ti" + } + ListElement { + text: "V" + } + ListElement { + text: "Cr" + } + ListElement { + text: "Mn" + } + ListElement { + text: "Fe" + } + ListElement { + text: "Co" + } + ListElement { + text: "Ni" + } + ListElement { + text: "Cu" + } + ListElement { + text: "Zn" + } + ListElement { + text: "Ga" + } + ListElement { + text: "Ge" + } + ListElement { + text: "As" + } + ListElement { + text: "Se" + } + ListElement { + text: "Br" + } + ListElement { + text: "Kr" + } + ListElement { + text: "Rb" + } + ListElement { + text: "Sr" + } + ListElement { + text: "Y" + } + ListElement { + text: "Zr" + } + ListElement { + text: "Nb" + } + ListElement { + text: "Mo" + } + ListElement { + text: "Tc" + } + ListElement { + text: "Ru" + } + ListElement { + text: "Rh" + } + ListElement { + text: "Pd" + } + ListElement { + text: "Ag" + } + ListElement { + text: "Cd" + } + ListElement { + text: "In" + } + ListElement { + text: "Sn" + } + ListElement { + text: "Sb" + } + ListElement { + text: "Te" + } + ListElement { + text: "I" + } + ListElement { + text: "Xe" + } + ListElement { + text: "Cs" + } + ListElement { + text: "Ba" + } + ListElement { + text: "La" + } + ListElement { + text: "Ce" + } + ListElement { + text: "Pr" + } + ListElement { + text: "Nd" + } + ListElement { + text: "Pm" + } + ListElement { + text: "Sm" + } + ListElement { + text: "Eu" + } + ListElement { + text: "Gd" + } + ListElement { + text: "Tb" + } + ListElement { + text: "Dy" + } + ListElement { + text: "Ho" + } + ListElement { + text: "Er" + } + ListElement { + text: "Tm" + } + ListElement { + text: "Yb" + } + ListElement { + text: "Lu" + } + ListElement { + text: "Hf" + } + ListElement { + text: "Ta" + } + ListElement { + text: "W" + } + ListElement { + text: "Re" + } + ListElement { + text: "Os" + } + ListElement { + text: "Ir" + } + ListElement { + text: "Pt" + } + ListElement { + text: "Au" + } + ListElement { + text: "Hg" + } + ListElement { + text: "Tl" + } + ListElement { + text: "Pb" + } + ListElement { + text: "Bi" + } + ListElement { + text: "Po" + } + ListElement { + text: "At" + } + ListElement { + text: "Rn" + } + ListElement { + text: "Fr" + } + ListElement { + text: "Ra" + } + ListElement { + text: "Ac" + } + ListElement { + text: "Th" + } + ListElement { + text: "Pa" + } + ListElement { + text: "U" + } + ListElement { + text: "Np" + } + ListElement { + text: "Pu" + } + ListElement { + text: "Am" + } + ListElement { + text: "Cm" + } + ListElement { + text: "Bk" + } + ListElement { + text: "Cf" + } + ListElement { + text: "Es" + } + ListElement { + text: "Fm" + } + ListElement { + text: "Md" + } + ListElement { + text: "No" + } + ListElement { + text: "Lr" + } + ListElement { + text: "Rf" + } + ListElement { + text: "Db" + } + ListElement { + text: "Sg" + } + ListElement { + text: "Bh" + } + ListElement { + text: "Hs" + } + ListElement { + text: "Mt" + } + ListElement { + text: "Ds" + } + ListElement { + text: "Rg" + } + ListElement { + text: "Cn" + } + ListElement { + text: "Nh" + } + ListElement { + text: "Fl" + } + ListElement { + text: "Mc" + } + ListElement { + text: "Lv" + } + ListElement { + text: "Ts" + } + ListElement { + text: "Og" + } + ListElement { + text: "Phantom" + } } } diff --git a/src/gui/qml/nodeGraph/GraphView.qml b/src/gui/qml/nodeGraph/GraphView.qml index 2e46e30681..39e5c93a5f 100644 --- a/src/gui/qml/nodeGraph/GraphView.qml +++ b/src/gui/qml/nodeGraph/GraphView.qml @@ -117,12 +117,13 @@ Pane { MenuItem { text: "Species" + onClicked: speciesDialog.open() + SpeciesDialog { - id: speciesDialog - graphModel: graphRoot.rootModel - } + id: speciesDialog - onClicked: speciesDialog.open() + graphModel: graphRoot.rootModel + } } } } diff --git a/src/gui/qml/nodeGraph/SpeciesDialog.qml b/src/gui/qml/nodeGraph/SpeciesDialog.qml index 447854d23f..6538729422 100644 --- a/src/gui/qml/nodeGraph/SpeciesDialog.qml +++ b/src/gui/qml/nodeGraph/SpeciesDialog.qml @@ -4,11 +4,10 @@ import QtQuick.Layouts import Qt.labs.qmlmodels import Dissolve - Dialog { id: root - required property variant graphModel; + required property variant graphModel standardButtons: Dialog.Ok | Dialog.Cancel title: "Define Species: " + sp.name @@ -19,64 +18,91 @@ Dialog { SpeciesModel { id: sp - } + } ColumnLayout { RowLayout { - Text {text: "Name"} + Text { + text: "Name" + } TextField { placeholderText: sp.name + onTextChanged: sp.name = text } } GroupBox { id: atomBox + title: "Atoms" + ColumnLayout { RowLayout { - Text { text: "Element" } - ElementComboBox { id:elementField } - Text { text: "X" } + Text { + text: "Element" + } + ElementComboBox { + id: elementField + + } + Text { + text: "X" + } TextField { id: xField - validator: DoubleValidator {} + + validator: DoubleValidator { + } + } + Text { + text: "Y" } - Text { text: "Y" } TextField { id: yField - validator: DoubleValidator {} + + validator: DoubleValidator { + } + } + Text { + text: "Z" } - Text { text: "Z" } TextField { id: zField - validator: DoubleValidator {} + + validator: DoubleValidator { + } + } + Text { + text: "Charge" } - Text { text: "Charge" } TextField { id: chargeField - validator: DoubleValidator {} + + validator: DoubleValidator { + } } Button { + enabled: xField.text != "" && yField.text != "" && zField.text != "" && chargeField.text != "" text: "+" - enabled: xField.text != "" && yField.text!= "" && zField.text!= "" && chargeField.text != ""; - onClicked: sp.atoms.addAtom(elementField.currentText, xField.text, yField.text, zField.text, chargeField.text); + + onClicked: sp.atoms.addAtom(elementField.currentText, xField.text, yField.text, zField.text, chargeField.text) } } TableView { Layout.fillHeight: true Layout.fillWidth: true - implicitHeight: 200 - implicitWidth: zField.width * sp.atoms.columnCount() clip: true columnSpacing: 1 - rowSpacing: 1 - + implicitHeight: 200 + implicitWidth: zField.width * sp.atoms.columnCount() model: sp.atoms + rowSpacing: 1 delegate: TextField { - text: display - implicitWidth: parent.parent.width / 6 - 1 implicitHeight: 20 + implicitWidth: parent.parent.width / 6 - 1 + text: display + onTextChanged: edit = text } } @@ -84,35 +110,48 @@ Dialog { } GridLayout { columns: 2 + GroupBox { title: "Bonds" + ColumnLayout { RowLayout { - Text { text: "I" } + Text { + text: "I" + } TextField { id: bondI - validator: IntValidator {} + + validator: IntValidator { + } + } + Text { + text: "J" } - Text { text: "J" } TextField { id: bondJ - validator: IntValidator {} + + validator: IntValidator { + } } Button { + enabled: bondI.text != "" && bondJ.text != "" text: "+" - enabled: bondI.text != "" && bondJ.text!= ""; - onClicked: sp.addBond(bondI.text, bondJ.text); + + onClicked: sp.addBond(bondI.text, bondJ.text) } } TableView { Layout.fillHeight: true Layout.fillWidth: true implicitHeight: 200 - implicitWidth: bondI.width*sp.bonds.columnCount() + implicitWidth: bondI.width * sp.bonds.columnCount() model: sp.bonds + delegate: TextField { text: display width: 10 + onTextChanged: edit = text } } @@ -120,38 +159,54 @@ Dialog { } GroupBox { title: "Angles" + ColumnLayout { RowLayout { - Text { text: "I" } + Text { + text: "I" + } TextField { id: angleI - validator: IntValidator {} + + validator: IntValidator { + } + } + Text { + text: "J" } - Text { text: "J" } TextField { id: angleJ - validator: IntValidator {} + + validator: IntValidator { + } + } + Text { + text: "K" } - Text { text: "K" } TextField { id: angleK - validator: IntValidator {} + + validator: IntValidator { + } } Button { + enabled: angleI.text != "" && angleJ.text != "" && angleK.text != "" text: "+" - enabled: angleI.text != "" && angleJ.text!= "" && angleK.text != ""; - onClicked: sp.addAngle(angleI.text, angleJ.text, angleK.text); + + onClicked: sp.addAngle(angleI.text, angleJ.text, angleK.text) } } TableView { Layout.fillHeight: true Layout.fillWidth: true implicitHeight: 200 - implicitWidth: angleI.width*sp.angles.columnCount() + implicitWidth: angleI.width * sp.angles.columnCount() model: sp.angles + delegate: TextField { text: display width: 10 + onTextChanged: edit = text } } @@ -159,88 +214,127 @@ Dialog { } GroupBox { title: "Torsions" + ColumnLayout { RowLayout { - Text { text: "I" } + Text { + text: "I" + } TextField { id: torsionI - validator: IntValidator {} + + validator: IntValidator { + } + } + Text { + text: "J" } - Text { text: "J" } TextField { id: torsionJ - validator: IntValidator {} + + validator: IntValidator { + } + } + Text { + text: "K" } - Text { text: "K" } TextField { id: torsionK - validator: IntValidator {} + + validator: IntValidator { + } + } + Text { + text: "L" } - Text { text: "L" } TextField { id: torsionL - validator: IntValidator {} + + validator: IntValidator { + } } Button { + enabled: torsionI.text != "" && torsionJ.text != "" && torsionK.text != "" && torsionL.text != "" text: "+" - enabled: torsionI.text != "" && torsionJ.text!= "" && torsionK.text != "" && torsionL.text != ""; - onClicked: sp.addTorsion(torsionI.text, torsionJ.text, torsionK.text, torsionL.text); + + onClicked: sp.addTorsion(torsionI.text, torsionJ.text, torsionK.text, torsionL.text) } } TableView { Layout.fillHeight: true Layout.fillWidth: true implicitHeight: 200 - implicitWidth: torsionI.width*sp.torsions.columnCount() + implicitWidth: torsionI.width * sp.torsions.columnCount() model: sp.torsions + delegate: TextField { text: display width: 10 + onTextChanged: edit = text } } } } - GroupBox { title: "Impropers" + ColumnLayout { RowLayout { - Text { text: "I" } + Text { + text: "I" + } TextField { id: improperI - validator: IntValidator {} + + validator: IntValidator { + } + } + Text { + text: "J" } - Text { text: "J" } TextField { id: improperJ - validator: IntValidator {} + + validator: IntValidator { + } + } + Text { + text: "K" } - Text { text: "K" } TextField { id: improperK - validator: IntValidator {} + + validator: IntValidator { + } + } + Text { + text: "L" } - Text { text: "L" } TextField { id: improperL - validator: IntValidator {} + + validator: IntValidator { + } } Button { + enabled: improperI.text != "" && improperJ.text != "" && improperK.text != "" && improperL.text != "" text: "+" - enabled: improperI.text != "" && improperJ.text!= "" && improperK.text != "" && improperL.text != ""; - onClicked: sp.addImproper(improperI.text, improperJ.text, improperK.text, improperL.text); + + onClicked: sp.addImproper(improperI.text, improperJ.text, improperK.text, improperL.text) } } TableView { Layout.fillHeight: true Layout.fillWidth: true implicitHeight: 200 - implicitWidth: improperI.width*sp.impropers.columnCount() + implicitWidth: improperI.width * sp.impropers.columnCount() model: sp.impropers + delegate: TextField { text: display width: 10 + onTextChanged: edit = text } } diff --git a/src/gui/qml/simulationDataManager/SimulationDataManager.qml b/src/gui/qml/simulationDataManager/SimulationDataManager.qml index 067c488e51..3cc8d759d6 100644 --- a/src/gui/qml/simulationDataManager/SimulationDataManager.qml +++ b/src/gui/qml/simulationDataManager/SimulationDataManager.qml @@ -59,19 +59,18 @@ Page { } TableView { id: table - anchors.fill: parent property variant colWidths: [300, 300, 50] Layout.fillHeight: true Layout.fillWidth: true + anchors.fill: parent boundsBehavior: Flickable.StopAtBounds clip: true columnSpacing: 1 columnWidthProvider: function (column) { return colWidths[column]; } - model: proxy rowSpacing: 1 From d4f9b3d394582dbc75951f5f57b6ff58778c038e Mon Sep 17 00:00:00 2001 From: Adam Washington Date: Thu, 20 Nov 2025 15:00:04 +0000 Subject: [PATCH 29/31] Fixup from personal review --- src/gui/models/nodeGraph/graphModel.cpp | 1 + src/gui/models/speciesAtomModel.cpp | 10 -- src/gui/models/speciesModel.cpp | 103 +------------------- src/gui/models/speciesModel.h | 1 + src/gui/qml/nodeGraph/ParameterDelegate.qml | 1 - src/nodes/CMakeLists.txt | 1 - 6 files changed, 3 insertions(+), 114 deletions(-) diff --git a/src/gui/models/nodeGraph/graphModel.cpp b/src/gui/models/nodeGraph/graphModel.cpp index 065c903ff6..6de96b3359 100644 --- a/src/gui/models/nodeGraph/graphModel.cpp +++ b/src/gui/models/nodeGraph/graphModel.cpp @@ -87,6 +87,7 @@ void GraphModel::descend(int index) } } +// Add a pre-created node void GraphModel::addNode(std::unique_ptr node, std::string_view name) { nodes_.beginInsertRows({}, graph_->nodes().size(), graph_->nodes().size() + 1); diff --git a/src/gui/models/speciesAtomModel.cpp b/src/gui/models/speciesAtomModel.cpp index 011374e852..a227c076e9 100644 --- a/src/gui/models/speciesAtomModel.cpp +++ b/src/gui/models/speciesAtomModel.cpp @@ -122,16 +122,6 @@ bool SpeciesAtomModel::setData(const QModelIndex &index, const QVariant &value, item.setAtomType(std::const_pointer_cast(it->first->shared_from_this())); } break; - // FIXME: we don't have atom types yet - // { - // auto atomType = coreData_.findAtomType(value.toString().toStdString()); - // if (!atomType) - // return false; - // item.setAtomType(atomType); - // species_->updateIsotopologues(); - // Q_EMIT atomTypeChanged(); - // } - // break; case 2: case 3: case 4: diff --git a/src/gui/models/speciesModel.cpp b/src/gui/models/speciesModel.cpp index dc2d17f2e4..5c1d280e0b 100644 --- a/src/gui/models/speciesModel.cpp +++ b/src/gui/models/speciesModel.cpp @@ -40,6 +40,7 @@ SpeciesImproperModel *SpeciesModel::impropers() { return &impropers_; } // Atom information SpeciesAtomModel *SpeciesModel::atoms() { return &atoms_; } +// Produce this species node on the given graph void SpeciesModel::create(QVariant graphModel) { auto model = graphModel.value(); @@ -76,105 +77,3 @@ void SpeciesModel::addImproper(int i, int j, int k, int l) species_->addImproper(i - 1, j - 1, k - 1, l - 1); impropers_.endInsertRows(); } - -// const Species *SpeciesModel::rawData(const QModelIndex &index) const -// { -// assert(species_); -// return species_->get()[index.row()].get(); -// } - -// // Refresh model data -// void SpeciesModel::reset() -// { -// beginResetModel(); -// endResetModel(); -// } - -// /* -// * QAbstractItemModel overrides -// */ - -// int SpeciesModel::rowCount(const QModelIndex &parent) const -// { -// Q_UNUSED(parent); -// return species_ ? species_->get().size() : 0; -// } - -// QVariant SpeciesModel::data(const QModelIndex &index, int role) const -// { -// if (!index.isValid()) -// return {}; -// switch (role) -// { -// case (Qt::DisplayRole): -// return QString::fromStdString(std::string(rawData(index)->name())); -// case (Qt::CheckStateRole): -// if (checkedItems_) -// { -// return std::find(checkedItems_->get().begin(), checkedItems_->get().end(), rawData(index)) == -// checkedItems_->get().end() -// ? Qt::Unchecked -// : Qt::Checked; -// } -// else -// { -// return {}; -// } -// case (static_cast(SpeciesUserRole::RawData)): -// return QVariant::fromValue(rawData(index)); -// case (static_cast(SpeciesUserRole::BondsCount)): -// return QVariant::fromValue(rawData(index)->nBonds()); -// case (static_cast(SpeciesUserRole::AnglesCount)): -// return QVariant::fromValue(rawData(index)->nAngles()); -// case (static_cast(SpeciesUserRole::TorsionsCount)): -// return QVariant::fromValue(rawData(index)->nTorsions()); -// case (static_cast(SpeciesUserRole::ImpropersCount)): -// return QVariant::fromValue(rawData(index)->nImpropers()); -// default: -// return {}; -// } -// } - -// bool SpeciesModel::setData(const QModelIndex &index, const QVariant &value, int role) -// { -// if (role == Qt::CheckStateRole && checkedItems_) -// { -// auto &xitems = checkedItems_->get(); -// if (value.value() == Qt::Checked) -// { -// if (std::find(xitems.begin(), xitems.end(), rawData(index)) == xitems.end()) -// xitems.push_back(rawData(index)); -// } -// else -// xitems.erase(std::remove(xitems.begin(), xitems.end(), rawData(index)), xitems.end()); - -// Q_EMIT dataChanged(index, index); - -// return true; -// } - -// return false; -// } - -// Qt::ItemFlags SpeciesModel::flags(const QModelIndex &index) const -// { -// return checkedItems_ ? Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable -// : Qt::ItemIsSelectable | Qt::ItemIsEnabled; -// } - -// QVariant SpeciesModel::headerData(int section, Qt::Orientation orientation, int role) const -// { -// if (role != Qt::DisplayRole) -// return {}; - -// if (orientation == Qt::Horizontal) -// switch (section) -// { -// case 0: -// return "Name"; -// default: -// return {}; -// } - -// return {}; -// } diff --git a/src/gui/models/speciesModel.h b/src/gui/models/speciesModel.h index b2573db310..35c3d5ae6e 100644 --- a/src/gui/models/speciesModel.h +++ b/src/gui/models/speciesModel.h @@ -81,6 +81,7 @@ class SpeciesModel : public QObject void nameChanged(); public Q_SLOTS: + // Produce this species node on the given graph void create(QVariant graphModel); void addBond(int i, int j); void addAngle(int i, int j, int k); diff --git a/src/gui/qml/nodeGraph/ParameterDelegate.qml b/src/gui/qml/nodeGraph/ParameterDelegate.qml index f811703bba..b91266fa60 100644 --- a/src/gui/qml/nodeGraph/ParameterDelegate.qml +++ b/src/gui/qml/nodeGraph/ParameterDelegate.qml @@ -2,7 +2,6 @@ import QtQuick import QtQuick.Controls import QtQuick.Layouts import Qt.labs.qmlmodels -import Dissolve DelegateChooser { id: root diff --git a/src/nodes/CMakeLists.txt b/src/nodes/CMakeLists.txt index ac507e9f6d..f26e9a23f0 100644 --- a/src/nodes/CMakeLists.txt +++ b/src/nodes/CMakeLists.txt @@ -4,7 +4,6 @@ file( "./*.cpp" ) - file( GLOB_RECURSE node_headers RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} From 1abf327a30a55ee206023836db02ab7ab35ee2d3 Mon Sep 17 00:00:00 2001 From: Adam Washington Date: Thu, 20 Nov 2025 15:43:52 +0000 Subject: [PATCH 30/31] Deactivate last bits of old GUI --- src/gui/CMakeLists.txt | 136 --------------------------------- src/modules/CMakeLists.txt | 45 +++-------- src/modules/widgetProducer.cpp | 124 +++++++++++++++--------------- 3 files changed, 72 insertions(+), 233 deletions(-) diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index de2ac8fd12..eb3362a315 100755 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -10,142 +10,6 @@ add_library( wizardFooter.ui wizardHeader.h wizardHeader.ui - # Viewers - configurationViewer.cpp - configurationViewer_input.cpp - configurationViewer_interaction.cpp - configurationViewer_render.cpp - configurationViewer.h - configurationViewerWidget.cpp - configurationViewerWidget.h - configurationViewerWidget.ui - dataViewer.cpp - dataViewer_input.cpp - dataViewer_interaction.cpp - dataViewer_contextMenu.cpp - dataViewer_render.cpp - dataViewer.h - dataWidget.cpp - dataWidget.h - dataWidget.ui - selectSymbol.cpp - selectSymbol.h - selectSymbol.ui - speciesEditor.cpp - speciesEditor.h - speciesEditor.ui - speciesViewer.h - speciesViewer.cpp - speciesViewer_input.cpp - speciesViewer_interaction.cpp - speciesViewer_render.cpp - speciesWidget.cpp - speciesWidget.h - speciesWidget.ui - viewer.cpp - viewer_input.cpp - viewer_interaction.cpp - viewer_options.cpp - viewer_query.cpp - viewer_render.cpp - viewer_renderables.cpp - viewer_view.cpp - viewer.h - # Widgets and Wizards - selectAtomTypeWidget.cpp - selectAtomTypeWidget.h - selectAtomTypeWidget.ui - selectForcefieldWidget.cpp - selectForcefieldWidget.h - selectForcefieldWidget.ui - # Dialogs - addConfigurationDialog.cpp - addConfigurationDialog.h - addConfigurationDialog.ui - addForcefieldTermsDialog.cpp - addForcefieldTermsDialog.h - copySpeciesTermsDialog.cpp - copySpeciesTermsDialog.h - copySpeciesTermsDialog.ui - createGrapheneSpeciesDialog.cpp - createGrapheneSpeciesDialog.h - createGrapheneSpeciesDialog.ui - dataManagerDialog.cpp - dataManagerDialog.h - editSpeciesDialog.cpp - editSpeciesDialog.h - editSpeciesDialog.ui - getConfigurationNameDialog.cpp - getConfigurationNameDialog.h - getConfigurationNameDialog.ui - getModuleLayerNameDialog.cpp - getModuleLayerNameDialog.h - getModuleLayerNameDialog.ui - getSpeciesNameDialog.cpp - getSpeciesNameDialog.h - getSpeciesNameDialog.ui - getTabNameDialog.cpp - getTabNameDialog.h - getTabNameDialog.ui - importCIFDialog.cpp - importCIFDialog.h - importCIFDialog.ui - importLigParGenDialog.cpp - importLigParGenDialog.h - importLigParGenDialog.ui - modifyChargesDialog.cpp - modifyChargesDialog.h - selectAtomTypeDialog.cpp - selectAtomTypeDialog.h - selectAtomTypeDialog.ui - selectElementDialog.cpp - selectElementDialog.h - selectElementDialog.ui - selectGenericItemDialog.cpp - selectGenericItemDialog.h - selectGenericItemDialog.ui - selectRestartFileDialog.cpp - selectRestartFileDialog.h - selectRestartFileDialog.ui - selectSpeciesDialog.cpp - selectSpeciesDialog.h - selectSpeciesDialog.ui - speciesCellDialog.cpp - speciesCellDialog.h - speciesCellDialog.ui - # Main Tabs - forcefieldTab.cpp - forcefieldTab.h - forcefieldTab.ui - layerTab.cpp - layerTab.h - layerTab.ui - mainTab.cpp - mainTab.h - mainTabsBar.cpp - mainTabsBar.h - mainTabsWidget.cpp - mainTabsWidget.h - messagesTab.cpp - messagesTab.h - messagesTab.ui - # Main UI - gui.cpp - gui_simulation.cpp - gui.h - gui.ui - menu_configuration.cpp - menu_file.cpp - menu_help.cpp - menu_layer.cpp - menu_simulation.cpp - menu_species.cpp - outputHandler.cpp - outputHandler.h - stockColours.cpp - stockColours.h - thread.cpp - thread.h ) target_include_directories( diff --git a/src/modules/CMakeLists.txt b/src/modules/CMakeLists.txt index 2308828569..79587e2754 100644 --- a/src/modules/CMakeLists.txt +++ b/src/modules/CMakeLists.txt @@ -59,42 +59,17 @@ macro(dissolve_add_module_gui modulename) message(STATUS "... GUI component 'module_${modulename}_gui': ${MODULEGUI_CPP} ${MODULEGUI_H} ${MODULEGUI_UI}") - # Add library target - add_library(module_${modulename}_gui ${MODULEGUI_CPP} ${MODULEGUI_H} ${MODULEGUI_UI}) - set(MODULEGUI_LINK_LIBS - ${MODULEGUI_LINK_LIBS} "module_${modulename}_gui" - CACHE INTERNAL "" FORCE - ) - - # Because Qt has its own way of checking for C++17 - if(MSVC) - target_compile_options(module_${modulename}_gui PUBLIC /Zc:__cplusplus) - endif(MSVC) + # # Add library target add_library(module_${modulename}_gui ${MODULEGUI_CPP} ${MODULEGUI_H} ${MODULEGUI_UI}) set(MODULEGUI_LINK_LIBS + # ${MODULEGUI_LINK_LIBS} "module_${modulename}_gui" CACHE INTERNAL "" FORCE ) - # Add dependency on main GUI components - add_dependencies(module_${modulename}_gui gui) + # # Add dependency on main GUI components add_dependencies(module_${modulename}_gui gui) - # Set common include dirs - target_include_directories( - module_${modulename}_gui - PRIVATE ${PROJECT_SOURCE_DIR}/src - ${PROJECT_BINARY_DIR}/src - ${CMAKE_BINARY_DIR}/src/gui/gui_autogen/include - ${CMAKE_BINARY_DIR}/src/gui/widgets/widgets_autogen/include - ${CMAKE_BINARY_DIR}/src/gui/gui_autogen/include_${CMAKE_BUILD_TYPE} - ${CMAKE_BINARY_DIR}/src/gui/widgets/widgets_autogen/include_${CMAKE_BUILD_TYPE} - ${Qt6Core_INCLUDE_DIRS} - ${Qt6Gui_INCLUDE_DIRS} - ${Qt6Widgets_INCLUDE_DIRS} - ${Qt6OpenGL_INCLUDE_DIRS} - ${Qt6OpenGLWidgets_INCLUDE_DIRS} - ${FREETYPE_INCLUDE_DIRS} - ) - target_link_libraries( - module_${modulename}_gui - PRIVATE base - PUBLIC ${THREADING_LINK_LIBS} - ) + # # Set common include dirs target_include_directories( module_${modulename}_gui PRIVATE ${PROJECT_SOURCE_DIR}/src + # ${PROJECT_BINARY_DIR}/src ${CMAKE_BINARY_DIR}/src/gui/gui_autogen/include ${CMAKE_BINARY_DIR}/src/gui/widgets/widgets_autogen/include + # ${CMAKE_BINARY_DIR}/src/gui/gui_autogen/include_${CMAKE_BUILD_TYPE} + # ${CMAKE_BINARY_DIR}/src/gui/widgets/widgets_autogen/include_${CMAKE_BUILD_TYPE} ${Qt6Core_INCLUDE_DIRS} ${Qt6Gui_INCLUDE_DIRS} + # ${Qt6Widgets_INCLUDE_DIRS} ${Qt6OpenGL_INCLUDE_DIRS} ${Qt6OpenGLWidgets_INCLUDE_DIRS} ${FREETYPE_INCLUDE_DIRS} ) target_link_libraries( + # module_${modulename}_gui PRIVATE base PUBLIC ${THREADING_LINK_LIBS} ) endmacro() # Module subdirectories @@ -129,7 +104,7 @@ target_include_directories( if(GUI) add_library(moduleWidgetProducer widget.cpp widgetProducer.cpp widget.h widgetProducer.h) - add_dependencies(moduleWidgetProducer ${MODULEGUI_LINK_LIBS}) + # add_dependencies(moduleWidgetProducer ${MODULEGUI_LINK_LIBS}) # Because Qt has its own way of checking for C++17 if(MSVC) diff --git a/src/modules/widgetProducer.cpp b/src/modules/widgetProducer.cpp index b56f65b6d4..12b56b98e9 100644 --- a/src/modules/widgetProducer.cpp +++ b/src/modules/widgetProducer.cpp @@ -3,102 +3,102 @@ #include "modules/widgetProducer.h" #include "modules/accumulate/accumulate.h" -#include "modules/accumulate/gui/accumulateWidget.h" +// #include "modules/accumulate/gui/accumulateWidget.h" #include "modules/angle/angle.h" -#include "modules/angle/gui/angleWidget.h" +// #include "modules/angle/gui/angleWidget.h" #include "modules/atomShake/atomShake.h" -#include "modules/atomShake/gui/atomShakeWidget.h" +// #include "modules/atomShake/gui/atomShakeWidget.h" #include "modules/avgMol/avgMol.h" -#include "modules/avgMol/gui/avgMolWidget.h" +// #include "modules/avgMol/gui/avgMolWidget.h" #include "modules/axisAngle/axisAngle.h" -#include "modules/axisAngle/gui/axisAngleWidget.h" +// #include "modules/axisAngle/gui/axisAngleWidget.h" #include "modules/benchmark/benchmark.h" -#include "modules/benchmark/gui/benchmarkWidget.h" +// #include "modules/benchmark/gui/benchmarkWidget.h" #include "modules/bragg/bragg.h" -#include "modules/bragg/gui/braggWidget.h" +// #include "modules/bragg/gui/braggWidget.h" #include "modules/clustering/clustering.h" -#include "modules/clustering/gui/clusteringWidget.h" +// #include "modules/clustering/gui/clusteringWidget.h" #include "modules/compare/compare.h" -#include "modules/compare/gui/compareWidget.h" +// #include "modules/compare/gui/compareWidget.h" #include "modules/dAngle/dAngle.h" -#include "modules/dAngle/gui/dAngleWidget.h" +// #include "modules/dAngle/gui/dAngleWidget.h" #include "modules/energy/energy.h" -#include "modules/energy/gui/energyWidget.h" +// #include "modules/energy/gui/energyWidget.h" #include "modules/epsr/epsr.h" -#include "modules/epsr/gui/epsrWidget.h" +// #include "modules/epsr/gui/epsrWidget.h" #include "modules/epsrManager/epsrManager.h" -#include "modules/epsrManager/gui/epsrManagerWidget.h" +// #include "modules/epsrManager/gui/epsrManagerWidget.h" #include "modules/geomOpt/geomOpt.h" -#include "modules/geomOpt/gui/geomOptWidget.h" +// #include "modules/geomOpt/gui/geomOptWidget.h" #include "modules/gr/gr.h" -#include "modules/gr/gui/grWidget.h" -#include "modules/histogramCN/gui/histogramCNWidget.h" +// #include "modules/gr/gui/grWidget.h" +// #include "modules/histogramCN/gui/histogramCNWidget.h" #include "modules/histogramCN/histogramCN.h" -#include "modules/intraAngle/gui/intraAngleWidget.h" +// #include "modules/intraAngle/gui/intraAngleWidget.h" #include "modules/intraAngle/intraAngle.h" -#include "modules/intraDistance/gui/intraDistanceWidget.h" +// #include "modules/intraDistance/gui/intraDistanceWidget.h" #include "modules/intraDistance/intraDistance.h" -#include "modules/modifierOSites/gui/modifierOSitesWidget.h" +// #include "modules/modifierOSites/gui/modifierOSitesWidget.h" #include "modules/modifierOSites/modifierOSites.h" -#include "modules/moleculeTorsion/gui/moleculeTorsionWidget.h" +// #include "modules/moleculeTorsion/gui/moleculeTorsionWidget.h" #include "modules/moleculeTorsion/moleculeTorsion.h" -#include "modules/neutronSQ/gui/neutronSQWidget.h" +// #include "modules/neutronSQ/gui/neutronSQWidget.h" #include "modules/neutronSQ/neutronSQ.h" -#include "modules/orientedSDF/gui/orientedSDFWidget.h" +// #include "modules/orientedSDF/gui/orientedSDFWidget.h" #include "modules/orientedSDF/orientedSDF.h" -#include "modules/qSpecies/gui/qSpeciesWidget.h" +// #include "modules/qSpecies/gui/qSpeciesWidget.h" #include "modules/qSpecies/qSpecies.h" -#include "modules/sdf/gui/sdfWidget.h" +// #include "modules/sdf/gui/sdfWidget.h" #include "modules/sdf/sdf.h" -#include "modules/siteRDF/gui/siteRDFWidget.h" +// #include "modules/siteRDF/gui/siteRDFWidget.h" #include "modules/siteRDF/siteRDF.h" -#include "modules/skeleton/gui/skeletonWidget.h" +// #include "modules/skeleton/gui/skeletonWidget.h" #include "modules/skeleton/skeleton.h" -#include "modules/sq/gui/sqWidget.h" +// #include "modules/sq/gui/sqWidget.h" #include "modules/sq/sq.h" -#include "modules/test/gui/testWidget.h" +// #include "modules/test/gui/testWidget.h" #include "modules/test/test.h" -#include "modules/tr/gui/trWidget.h" +// #include "modules/tr/gui/trWidget.h" #include "modules/tr/tr.h" -#include "modules/voxelDensity/gui/voxelDensityWidget.h" +// #include "modules/voxelDensity/gui/voxelDensityWidget.h" #include "modules/voxelDensity/voxelDensity.h" -#include "modules/xRaySQ/gui/xRaySQWidget.h" +// #include "modules/xRaySQ/gui/xRaySQWidget.h" #include "modules/xRaySQ/xRaySQ.h" #include ModuleWidgetProducer::ModuleWidgetProducer() { - registerProducer(); - registerProducer(); - registerProducer(); - registerProducer(); - registerProducer(); - registerProducer(); - registerProducer(); - registerProducer(); - registerProducer(); - registerProducer(); - registerProducer(); - registerProducer(); - registerProducer(); - registerProducer(); - registerProducer(); - registerProducer(); - registerProducer(); - registerProducer(); - registerProducer(); - registerProducer(); - registerProducer(); - registerProducer(); - registerProducer(); - registerProducer(); - registerProducer(); - registerProducer(); - registerProducer(); - registerProducer(); - registerProducer(); - registerProducer(); - registerProducer(); + // registerProducer(); + // registerProducer(); + // registerProducer(); + // registerProducer(); + // registerProducer(); + // registerProducer(); + // registerProducer(); + // registerProducer(); + // registerProducer(); + // registerProducer(); + // registerProducer(); + // registerProducer(); + // registerProducer(); + // registerProducer(); + // registerProducer(); + // registerProducer(); + // registerProducer(); + // registerProducer(); + // registerProducer(); + // registerProducer(); + // registerProducer(); + // registerProducer(); + // registerProducer(); + // registerProducer(); + // registerProducer(); + // registerProducer(); + // registerProducer(); + // registerProducer(); + // registerProducer(); + // registerProducer(); + // registerProducer(); } /* From d00006e2a5168dad97d61fd4c713da446aba7348 Mon Sep 17 00:00:00 2001 From: Adam Washington Date: Thu, 20 Nov 2025 16:55:02 +0000 Subject: [PATCH 31/31] No special windows build for keywordWidgets --- .github/workflows/build/windows/action.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/build/windows/action.yml b/.github/workflows/build/windows/action.yml index 1b9546d7b8..2649661d21 100644 --- a/.github/workflows/build/windows/action.yml +++ b/.github/workflows/build/windows/action.yml @@ -174,7 +174,6 @@ runs: TEMPD=$(mktemp -d) mkdir -p $TEMPD/bin cmake ../ -G Ninja -DCMAKE_BUILD_TYPE:STRING="Release" -DCMAKE_C_COMPILER=cl -DANTLR_EXECUTABLE:string=$ANTLR_EXE -DJava_JAVA_EXECUTABLE:string=$JAVA_EXE -DCMAKE_CXX_COMPILER=cl -DMULTI_THREADING:bool=${{ inputs.threading }} -DGUI:bool=true -DCMAKE_INSTALL_PREFIX:PATH=$TEMPD - cmake --build . --config Release --target keywordWidgets cmake --build . --config Release cp bin/* $TEMPD/bin ninja install