Skip to content

Commit

Permalink
Implement poll field length limiters in GUI form
Browse files Browse the repository at this point in the history
  • Loading branch information
jamescowens committed Feb 24, 2024
1 parent 7a6e722 commit 1815491
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 8 deletions.
8 changes: 4 additions & 4 deletions src/gridcoin/voting/builders.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1158,19 +1158,19 @@ PollBuilder PollBuilder::AddAdditionalField(Poll::AdditionalField field)
ToString(POLL_MAX_ADDITIONAL_FIELDS_SIZE)));
}

if (field.m_name.size() > Poll::AdditionalField::MAX_N_OR_V_SIZE) {
if (field.m_name.size() > Poll::AdditionalField::MAX_NAME_SIZE) {
throw VotingError(strprintf(
_("Poll additional field name \"%s\" exceeds %s characters."),
field.m_name,
ToString(Poll::AdditionalField::MAX_N_OR_V_SIZE)));
ToString(Poll::AdditionalField::MAX_NAME_SIZE)));
}

if (field.m_value.size() > Poll::AdditionalField::MAX_N_OR_V_SIZE) {
if (field.m_value.size() > Poll::AdditionalField::MAX_VALUE_SIZE) {
throw VotingError(strprintf(
_("Poll additional field value \"%s\" for field name \"%s\" exceeds %s characters."),
field.m_value,
field.m_name,
ToString(Poll::AdditionalField::MAX_N_OR_V_SIZE)));
ToString(Poll::AdditionalField::MAX_VALUE_SIZE)));
}

if (m_poll->m_additional_fields.FieldExists(field.m_name)) {
Expand Down
14 changes: 10 additions & 4 deletions src/gridcoin/voting/poll.h
Original file line number Diff line number Diff line change
Expand Up @@ -203,9 +203,15 @@ class Poll
{
public:
//!
//! \brief The maximum length for a poll additional field name or value.
//! \brief The maximum length for a poll additional field name.
//!
static constexpr size_t MAX_N_OR_V_SIZE = 100;
static constexpr size_t MAX_NAME_SIZE = 100;

//!
//! \brief The maximum length for a poll additional field value. This is currently set to align with the
//! maximum Project URL length.
//!
static constexpr size_t MAX_VALUE_SIZE = 500;

std::string m_name;
std::string m_value;
Expand Down Expand Up @@ -244,8 +250,8 @@ class Poll
template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action)
{
READWRITE(LIMITED_STRING(m_name, MAX_N_OR_V_SIZE));
READWRITE(LIMITED_STRING(m_value, MAX_N_OR_V_SIZE));
READWRITE(LIMITED_STRING(m_name, MAX_NAME_SIZE));
READWRITE(LIMITED_STRING(m_value, MAX_VALUE_SIZE));
READWRITE(m_required);
}
}; // AdditionalField
Expand Down
39 changes: 39 additions & 0 deletions src/qt/voting/pollwizarddetailspage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// file COPYING or https://opensource.org/licenses/mit-license.php.

#include "main.h"
#include "qitemdelegate.h"
#include "qt/bitcoinunits.h"
#include "qt/decoration.h"
#include "qt/forms/voting/ui_pollwizarddetailspage.h"
Expand Down Expand Up @@ -54,6 +55,37 @@ class ChoicesListDelegate : public QStyledItemDelegate
}
}; // ChoicesListDelegate

//!
//! \brief Applies custom behavior to additional field items in the poll editor.
//!
class AdditionalFieldDelegate : public QItemDelegate
{
Q_OBJECT

public:
AdditionalFieldDelegate(QObject* parent = nullptr) : QItemDelegate(parent)
{
}

QWidget* createEditor(
QWidget* parent,
const QStyleOptionViewItem& option,
const QModelIndex& index) const override
{
QWidget* editor = QItemDelegate::createEditor(parent, option, index);

if (QLineEdit* line_edit = qobject_cast<QLineEdit*>(editor)) {
if (index.column() == AdditionalFieldsTableModel::Name) {
line_edit->setMaxLength(VotingModel::maxPollAdditionalFieldNameLength());
} else if (index.column() == AdditionalFieldsTableModel::Value) {
line_edit->setMaxLength(VotingModel::maxPollAdditionalFieldValueLength());
}
}

return editor;
}
}; // AdditionalFieldDelegate

//!
//! \brief Provides for QWizardPage::registerField() without a real widget.
//!
Expand Down Expand Up @@ -167,13 +199,20 @@ PollWizardDetailsPage::PollWizardDetailsPage(QWidget* parent)
ui->responseTypeList->addItem(tr("Multiple Choice"));

ChoicesListDelegate* choices_delegate = new ChoicesListDelegate(this);
AdditionalFieldDelegate* additonal_field_delegate = new AdditionalFieldDelegate(this);

ui->choicesList->setModel(m_choices_model.get());
ui->choicesList->setItemDelegate(choices_delegate);
ui->choicesFrame->hide();
ui->editChoiceButton->hide();
ui->removeChoiceButton->hide();

ui->additionalFieldsTableView->setItemDelegate(additonal_field_delegate);

ui->titleField->setMaxLength(m_voting_model->maxPollTitleLength());
ui->questionField->setMaxLength(m_voting_model->maxPollQuestionLength());
ui->urlField->setMaxLength(m_voting_model->maxPollUrlLength());

connect(
ui->responseTypeList, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
[=](int index) {
Expand Down
3 changes: 3 additions & 0 deletions src/qt/voting/pollwizardprojectpage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ PollWizardProjectPage::PollWizardProjectPage(QWidget* parent)
ui->removeWidget->hide();
ui->addRemoveStateLineEdit->hide();

ui->projectNameField->setMaxLength(m_voting_model->maxPollProjectNameLength());
ui->projectUrlField->setMaxLength(m_voting_model->maxPollProjectUrlLength());

QStringListModel* project_names_model = new QStringListModel(this);
QStringListModel* project_urls_model = new QStringListModel(this);

Expand Down
36 changes: 36 additions & 0 deletions src/qt/voting/votingmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,42 @@ int VotingModel::maxPollChoiceLabelLength()
return Poll::Choice::MAX_LABEL_SIZE;
}

int VotingModel::maxPollAdditionalFieldNameLength()
{
// Not strictly accurate: the protocol limits the max length in bytes, but
// Qt limits field lengths in UTF-8 characters which may be represented by
// more than one byte.
//
return Poll::AdditionalField::MAX_NAME_SIZE;
}

int VotingModel::maxPollAdditionalFieldValueLength()
{
// Not strictly accurate: the protocol limits the max length in bytes, but
// Qt limits field lengths in UTF-8 characters which may be represented by
// more than one byte.
//
return Poll::AdditionalField::MAX_VALUE_SIZE;
}

int VotingModel::maxPollProjectNameLength()
{
// Not strictly accurate: the protocol limits the max length in bytes, but
// Qt limits field lengths in UTF-8 characters which may be represented by
// more than one byte.
//
return Project::MAX_NAME_SIZE;
}

int VotingModel::maxPollProjectUrlLength()
{
// Not strictly accurate: the protocol limits the max length in bytes, but
// Qt limits field lengths in UTF-8 characters which may be represented by
// more than one byte.
//
return Project::MAX_URL_SIZE;
}

OptionsModel& VotingModel::getOptionsModel()
{
return m_options_model;
Expand Down
4 changes: 4 additions & 0 deletions src/qt/voting/votingmodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,10 @@ class VotingModel : public QObject
static int maxPollUrlLength();
static int maxPollQuestionLength();
static int maxPollChoiceLabelLength();
static int maxPollAdditionalFieldNameLength();
static int maxPollAdditionalFieldValueLength();
static int maxPollProjectNameLength();
static int maxPollProjectUrlLength();

OptionsModel& getOptionsModel();
QString getCurrentPollTitle() const;
Expand Down

0 comments on commit 1815491

Please sign in to comment.