From 95d164a6e6ab9cd246e5007f25b9c93be0621312 Mon Sep 17 00:00:00 2001 From: Rob Cutmore Date: Sat, 18 Mar 2017 07:49:46 -0400 Subject: [PATCH 1/3] Editor: use combo box when creating pathgrids Instead of using QLineEdit for user input, use a QComboBox populated with valid choices. This prevents user from being able to create a pathgrid for a non-existent cell. --- apps/opencs/view/world/pathgridcreator.cpp | 58 +++++++++++++++++++--- apps/opencs/view/world/pathgridcreator.hpp | 9 ++++ 2 files changed, 61 insertions(+), 6 deletions(-) diff --git a/apps/opencs/view/world/pathgridcreator.cpp b/apps/opencs/view/world/pathgridcreator.cpp index a305b1249..166acafd2 100644 --- a/apps/opencs/view/world/pathgridcreator.cpp +++ b/apps/opencs/view/world/pathgridcreator.cpp @@ -1,28 +1,74 @@ #include "pathgridcreator.hpp" +#include +#include +#include +#include + #include "../../model/world/data.hpp" +std::string CSVWorld::PathgridCreator::getId() const +{ + return mCell->currentText().toUtf8().constData(); +} + CSVWorld::PathgridCreator::PathgridCreator( CSMWorld::Data& data, QUndoStack& undoStack, const CSMWorld::UniversalId& id, bool relaxedIdRules ) : GenericCreator(data, undoStack, id, relaxedIdRules) -{} +{ + setManualEditing(false); + + QLabel *label = new QLabel("Cell ID", this); + insertBeforeButtons(label, false); + + // Create combo box with case-insensitive sorting. + mCell = new QComboBox(this); + QSortFilterProxyModel *proxyModel = new QSortFilterProxyModel; + QStringListModel *listModel = new QStringListModel; + proxyModel->setSourceModel(listModel); + proxyModel->setSortCaseSensitivity(Qt::CaseInsensitive); + mCell->setModel(proxyModel); + insertBeforeButtons(mCell, true); + + // Populate combo box with cells that don't have a pathgrid yet. + const CSMWorld::IdCollection& pathgrids = getData().getPathgrids(); + const CSMWorld::IdCollection& cells = getData().getCells(); + const int cellCount = cells.getSize(); + for (int i = 0; i < cellCount; ++i) + { + std::string cellId = cells.getId(i); + if (pathgrids.searchId(cellId) == -1) + { + mCell->addItem(QString::fromStdString(cellId)); + } + } + + mCell->model()->sort(0); + mCell->setCurrentIndex(0); +} std::string CSVWorld::PathgridCreator::getErrors() const { - std::string pathgridId = getId(); + std::string cellId = getId(); // Check user input for any errors. + // The last two checks, cell with existing pathgrid and non-existent cell, + // shouldn't be needed but we absolutely want to make sure they never happen. std::string errors; - if (pathgridId.empty()) + if (cellId.empty()) { - errors = "No Pathgrid ID entered"; + errors = "No cell ID selected"; } - else if (getData().getPathgrids().searchId(pathgridId) > -1) + else if (getData().getPathgrids().searchId(cellId) > -1) { - errors = "Pathgrid with this ID already exists"; + errors = "Pathgrid for selected cell ID already exists"; + } + else if (getData().getCells().searchId(cellId) == -1) + { + errors = "Cell with selected cell ID does not exist"; } return errors; diff --git a/apps/opencs/view/world/pathgridcreator.hpp b/apps/opencs/view/world/pathgridcreator.hpp index 10f64a0a7..5508fadd7 100644 --- a/apps/opencs/view/world/pathgridcreator.hpp +++ b/apps/opencs/view/world/pathgridcreator.hpp @@ -1,6 +1,8 @@ #ifndef PATHGRIDCREATOR_HPP #define PATHGRIDCREATOR_HPP +class QComboBox; + #include "genericcreator.hpp" namespace CSVWorld @@ -10,6 +12,13 @@ namespace CSVWorld { Q_OBJECT + QComboBox *mCell; + + private: + + /// \return Cell ID selected by user. + virtual std::string getId() const; + public: PathgridCreator( From 491fd3d0be333efb4696448818b681e0e4fadb2c Mon Sep 17 00:00:00 2001 From: Rob Cutmore Date: Sat, 18 Mar 2017 09:20:14 -0400 Subject: [PATCH 2/3] Editor: set combo box events for pathgrid creator - Handles when combo box should automatically gain or lose focus. - Checks user input when combo box selection changes. --- apps/opencs/view/world/pathgridcreator.cpp | 18 ++++++++++++++++++ apps/opencs/view/world/pathgridcreator.hpp | 11 +++++++++++ 2 files changed, 29 insertions(+) diff --git a/apps/opencs/view/world/pathgridcreator.cpp b/apps/opencs/view/world/pathgridcreator.cpp index 166acafd2..ae9ce7242 100644 --- a/apps/opencs/view/world/pathgridcreator.cpp +++ b/apps/opencs/view/world/pathgridcreator.cpp @@ -48,6 +48,8 @@ CSVWorld::PathgridCreator::PathgridCreator( mCell->model()->sort(0); mCell->setCurrentIndex(0); + + connect(mCell, SIGNAL (currentIndexChanged(const QString&)), this, SLOT (cellChanged())); } std::string CSVWorld::PathgridCreator::getErrors() const @@ -73,3 +75,19 @@ std::string CSVWorld::PathgridCreator::getErrors() const return errors; } + +void CSVWorld::PathgridCreator::focus() +{ + mCell->setFocus(); +} + +void CSVWorld::PathgridCreator::reset() +{ + CSVWorld::GenericCreator::reset(); + mCell->setCurrentIndex(0); +} + +void CSVWorld::PathgridCreator::cellChanged() +{ + update(); +} diff --git a/apps/opencs/view/world/pathgridcreator.hpp b/apps/opencs/view/world/pathgridcreator.hpp index 5508fadd7..6ed8004e2 100644 --- a/apps/opencs/view/world/pathgridcreator.hpp +++ b/apps/opencs/view/world/pathgridcreator.hpp @@ -29,6 +29,17 @@ namespace CSVWorld /// \return Error description for current user input. virtual std::string getErrors() const; + + /// \brief Set focus to cell ID input widget. + virtual void focus(); + + /// \brief Reset selected cell ID. + virtual void reset(); + + private slots: + + /// \brief Check user input for errors. + void cellChanged(); }; } From 0dcb6a9bd4b788964b84e42f25b9c687dc413612 Mon Sep 17 00:00:00 2001 From: Rob Cutmore Date: Sat, 18 Mar 2017 10:20:16 -0400 Subject: [PATCH 3/3] Editor: update pathgrid creator input on changes When data changes the cell input for pathgrid creator is repopulated with valid choices. This handles the case where a cell is added or removed, and also when a cell's pathgrid is added or completely removed. --- apps/opencs/view/world/pathgridcreator.cpp | 38 +++++++++++++--------- apps/opencs/view/world/pathgridcreator.hpp | 3 ++ 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/apps/opencs/view/world/pathgridcreator.cpp b/apps/opencs/view/world/pathgridcreator.cpp index ae9ce7242..980c031ca 100644 --- a/apps/opencs/view/world/pathgridcreator.cpp +++ b/apps/opencs/view/world/pathgridcreator.cpp @@ -33,22 +33,9 @@ CSVWorld::PathgridCreator::PathgridCreator( mCell->setModel(proxyModel); insertBeforeButtons(mCell, true); - // Populate combo box with cells that don't have a pathgrid yet. - const CSMWorld::IdCollection& pathgrids = getData().getPathgrids(); - const CSMWorld::IdCollection& cells = getData().getCells(); - const int cellCount = cells.getSize(); - for (int i = 0; i < cellCount; ++i) - { - std::string cellId = cells.getId(i); - if (pathgrids.searchId(cellId) == -1) - { - mCell->addItem(QString::fromStdString(cellId)); - } - } - - mCell->model()->sort(0); - mCell->setCurrentIndex(0); + setupCellsInput(); + connect(&getData(), SIGNAL (idListChanged()), this, SLOT (setupCellsInput())); connect(mCell, SIGNAL (currentIndexChanged(const QString&)), this, SLOT (cellChanged())); } @@ -91,3 +78,24 @@ void CSVWorld::PathgridCreator::cellChanged() { update(); } + +void CSVWorld::PathgridCreator::setupCellsInput() +{ + mCell->clear(); + + // Populate combo box with cells that don't have a pathgrid yet. + const CSMWorld::IdCollection& pathgrids = getData().getPathgrids(); + const CSMWorld::IdCollection& cells = getData().getCells(); + const int cellCount = cells.getSize(); + for (int i = 0; i < cellCount; ++i) + { + std::string cellId = cells.getId(i); + if (pathgrids.searchId(cellId) == -1) + { + mCell->addItem(QString::fromStdString(cellId)); + } + } + + mCell->model()->sort(0); + mCell->setCurrentIndex(0); +} diff --git a/apps/opencs/view/world/pathgridcreator.hpp b/apps/opencs/view/world/pathgridcreator.hpp index 6ed8004e2..7c4f7f705 100644 --- a/apps/opencs/view/world/pathgridcreator.hpp +++ b/apps/opencs/view/world/pathgridcreator.hpp @@ -40,6 +40,9 @@ namespace CSVWorld /// \brief Check user input for errors. void cellChanged(); + + /// \brief Setup cells in combo box. + void setupCellsInput(); }; }