townhintselector.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. /*
  2. * townhintselector.cpp, part of VCMI engine
  3. *
  4. * Authors: listed in file AUTHORS in main folder
  5. *
  6. * License: GNU General Public License v2.0 or later
  7. * Full text of license available in license.txt file, in main folder
  8. *
  9. */
  10. #include "StdInc.h"
  11. #include "townhintselector.h"
  12. #include "ui_townhintselector.h"
  13. enum modes { UNKNOWN, LIKE_ZONE, NOT_LIKE_ZONE, RELATED_TO_ZONE_TERRAIN };
  14. TownHintSelector::TownHintSelector(std::vector<rmg::ZoneOptions::CTownHints> & townHints) :
  15. ui(new Ui::TownHintSelector),
  16. townHints(townHints)
  17. {
  18. ui->setupUi(this);
  19. setWindowTitle(tr("Town hint Selector"));
  20. setWindowModality(Qt::ApplicationModal);
  21. ui->tableWidgetTownHints->setColumnCount(3);
  22. ui->tableWidgetTownHints->setRowCount(townHints.size() + 1);
  23. ui->tableWidgetTownHints->setHorizontalHeaderLabels({tr("Type"), tr("Value"), tr("Action")});
  24. std::map<modes, QString> values = {
  25. { LIKE_ZONE, tr("Like Zone") },
  26. { NOT_LIKE_ZONE, tr("Not like zone (comma separated)") },
  27. { RELATED_TO_ZONE_TERRAIN, tr("Related to zone terrain") }
  28. };
  29. auto addRow = [this, values](int mode, std::vector<TRmgTemplateZoneId> zones, int row){
  30. QComboBox *combo = new QComboBox();
  31. for(auto & item : values)
  32. combo->addItem(item.second, QVariant(static_cast<int>(item.first)));
  33. int index = combo->findData(static_cast<int>(mode));
  34. if (index != -1)
  35. combo->setCurrentIndex(index);
  36. ui->tableWidgetTownHints->setCellWidget(row, 0, combo);
  37. std::vector<std::string> values(zones.size());
  38. std::transform(zones.begin(), zones.end(), values.begin(), [](const int val) { return std::to_string(val); });
  39. std::string valuesText = boost::algorithm::join(values, ",");
  40. QLineEdit *lineEdit = new QLineEdit;
  41. QRegularExpression regex("^\\d+(,\\d+)*$");
  42. QRegularExpressionValidator *validator = new QRegularExpressionValidator(regex, lineEdit);
  43. lineEdit->setValidator(validator);
  44. lineEdit->setText(QString::fromStdString(valuesText));
  45. ui->tableWidgetTownHints->setCellWidget(row, 1, lineEdit);
  46. auto deleteButton = new QPushButton(tr("Delete"));
  47. ui->tableWidgetTownHints->setCellWidget(row, 2, deleteButton);
  48. connect(deleteButton, &QPushButton::clicked, this, [this, deleteButton]() {
  49. for (int r = 0; r < ui->tableWidgetTownHints->rowCount(); ++r) {
  50. if (ui->tableWidgetTownHints->cellWidget(r, 2) == deleteButton) {
  51. ui->tableWidgetTownHints->removeRow(r);
  52. break;
  53. }
  54. }
  55. });
  56. };
  57. for (int row = 0; row < townHints.size(); ++row)
  58. {
  59. int mode = UNKNOWN;
  60. std::vector<TRmgTemplateZoneId> zones;
  61. if(townHints[row].likeZone != rmg::ZoneOptions::NO_ZONE)
  62. {
  63. mode = LIKE_ZONE;
  64. zones = { townHints[row].likeZone };
  65. }
  66. else if(!townHints[row].notLikeZone.empty())
  67. {
  68. mode = NOT_LIKE_ZONE;
  69. zones = townHints[row].notLikeZone;
  70. }
  71. else if(townHints[row].relatedToZoneTerrain != rmg::ZoneOptions::NO_ZONE)
  72. {
  73. mode = RELATED_TO_ZONE_TERRAIN;
  74. zones = { townHints[row].relatedToZoneTerrain };
  75. }
  76. assert(mode != UNKNOWN);
  77. addRow(mode, zones, row);
  78. }
  79. auto addButton = new QPushButton("Add");
  80. ui->tableWidgetTownHints->setCellWidget(ui->tableWidgetTownHints->rowCount() - 1, 2, addButton);
  81. connect(addButton, &QPushButton::clicked, this, [this, addRow]() {
  82. ui->tableWidgetTownHints->insertRow(ui->tableWidgetTownHints->rowCount() - 1);
  83. addRow(LIKE_ZONE, std::vector<TRmgTemplateZoneId>({ 0 }), ui->tableWidgetTownHints->rowCount() - 2);
  84. });
  85. ui->tableWidgetTownHints->resizeColumnsToContents();
  86. ui->tableWidgetTownHints->setColumnWidth(0, 300);
  87. ui->tableWidgetTownHints->setColumnWidth(1, 150);
  88. show();
  89. }
  90. void TownHintSelector::showTownHintSelector(std::vector<rmg::ZoneOptions::CTownHints> & townHints)
  91. {
  92. auto * dialog = new TownHintSelector(townHints);
  93. dialog->setAttribute(Qt::WA_DeleteOnClose);
  94. dialog->exec();
  95. }
  96. void TownHintSelector::on_buttonBoxResult_accepted()
  97. {
  98. townHints.clear();
  99. for (int row = 0; row < ui->tableWidgetTownHints->rowCount() - 1; ++row) // iterate over all rows except the add button row
  100. {
  101. auto mode = static_cast<modes>(static_cast<QComboBox *>(ui->tableWidgetTownHints->cellWidget(row, 0))->currentData().toInt());
  102. auto text = static_cast<QLineEdit *>(ui->tableWidgetTownHints->cellWidget(row, 1))->text().toStdString();
  103. std::vector<std::string> values;
  104. boost::split(values, text, boost::is_any_of(","));
  105. if (!values.empty() && values.back().empty()) // remove "no number" after last comma; other cases are covered by regex
  106. values.pop_back();
  107. std::vector<int> numValues(values.size());
  108. std::transform(values.begin(), values.end(), numValues.begin(), [](const std::string& str) { return std::stoi(str); });
  109. rmg::ZoneOptions::CTownHints hint;
  110. switch (mode)
  111. {
  112. case LIKE_ZONE:
  113. hint.likeZone = numValues.at(0);
  114. break;
  115. case NOT_LIKE_ZONE:
  116. hint.notLikeZone = numValues;
  117. break;
  118. case RELATED_TO_ZONE_TERRAIN:
  119. hint.relatedToZoneTerrain = numValues.at(0);
  120. break;
  121. }
  122. townHints.push_back(hint);
  123. }
  124. close();
  125. }
  126. void TownHintSelector::on_buttonBoxResult_rejected()
  127. {
  128. close();
  129. }