#include "wildmonsearch.h" #include "ui_wildmonsearch.h" #include "project.h" enum ResultsColumn { Group, Field, Level, Chance, }; enum ResultsDataRole { MapName = Qt::UserRole, }; WildMonSearch::WildMonSearch(Project *project, QWidget *parent) : QDialog(parent), ui(new Ui::WildMonSearch), project(project) { setAttribute(Qt::WA_DeleteOnClose); ui->setupUi(this); // Set up species combo box ui->comboBox_Search->addItems(project->speciesToIconPath.keys()); ui->comboBox_Search->setCurrentText(QString()); ui->comboBox_Search->lineEdit()->setPlaceholderText(Project::getEmptySpeciesName()); connect(ui->comboBox_Search, &QComboBox::currentTextChanged, this, &WildMonSearch::updateResults); // Set up table header static const QStringList labels = {"Group", "Field", "Level", "Chance"}; ui->table_Results->setHorizontalHeaderLabels(labels); ui->table_Results->horizontalHeader()->setSectionResizeMode(ResultsColumn::Group, QHeaderView::Stretch); ui->table_Results->horizontalHeader()->setSectionResizeMode(ResultsColumn::Field, QHeaderView::ResizeToContents); ui->table_Results->horizontalHeader()->setSectionResizeMode(ResultsColumn::Level, QHeaderView::ResizeToContents); ui->table_Results->horizontalHeader()->setSectionResizeMode(ResultsColumn::Chance, QHeaderView::ResizeToContents); // Table is read-only ui->table_Results->setEditTriggers(QAbstractItemView::NoEditTriggers); ui->table_Results->setSelectionMode(QAbstractItemView::NoSelection); connect(ui->table_Results, &QTableWidget::cellDoubleClicked, this, &WildMonSearch::cellDoubleClicked); refresh(); } WildMonSearch::~WildMonSearch() { delete ui; } void WildMonSearch::refresh() { this->resultsCache.clear(); updatePercentageStrings(); updateResults(ui->comboBox_Search->currentText()); } void WildMonSearch::addTableEntry(const RowData &rowData) { int row = ui->table_Results->rowCount(); ui->table_Results->insertRow(row); auto groupItem = new QTableWidgetItem(rowData.groupName); groupItem->setData(ResultsDataRole::MapName, rowData.mapName); ui->table_Results->setItem(row, ResultsColumn::Group, groupItem); ui->table_Results->setItem(row, ResultsColumn::Field, new QTableWidgetItem(rowData.fieldName)); ui->table_Results->setItem(row, ResultsColumn::Level, new QTableWidgetItem(rowData.levelRange)); ui->table_Results->setItem(row, ResultsColumn::Chance, new QTableWidgetItem(rowData.chance)); } QList WildMonSearch::search(const QString &species) const { QList results; for (const auto &keyPair : this->project->wildMonData) { QString mapConstant = keyPair.first; for (const auto &grouplLabelPair : this->project->wildMonData[mapConstant]) { QString groupName = grouplLabelPair.first; WildPokemonHeader encounterHeader = this->project->wildMonData[mapConstant][groupName]; for (const auto &fieldNamePair : encounterHeader.wildMons) { QString fieldName = fieldNamePair.first; WildMonInfo monInfo = encounterHeader.wildMons[fieldName]; for (int slot = 0; slot < monInfo.wildPokemon.length(); slot++) { const WildPokemon wildMon = monInfo.wildPokemon.at(slot); if (wildMon.species == species) { RowData rowData; rowData.groupName = groupName; rowData.fieldName = fieldName; rowData.mapName = this->project->mapConstantsToMapNames.value(mapConstant, mapConstant); // If min and max level are the same display a single number, otherwise display a level range. rowData.levelRange = (wildMon.minLevel == wildMon.maxLevel) ? QString::number(wildMon.minLevel) : QString("%1-%2").arg(wildMon.minLevel).arg(wildMon.maxLevel); rowData.chance = this->percentageStrings[fieldName][slot]; results.append(rowData); } } } } } return results; } void WildMonSearch::updatePercentageStrings() { this->percentageStrings.clear(); for (const EncounterField &monField : this->project->wildMonFields) { QMap slotToPercentString; auto percentages = getWildEncounterPercentages(monField); for (int i = 0; i < percentages.length(); i++) { slotToPercentString.insert(i, QString::number(percentages.at(i) * 100, 'f', 2) + "%"); } this->percentageStrings[monField.name] = slotToPercentString; } } void WildMonSearch::updateResults(const QString &species) { ui->speciesIcon->setPixmap(this->project->getSpeciesIcon(species)); ui->table_Results->clearContents(); ui->table_Results->setRowCount(0); // Note: Per Qt docs, sorting should be disabled while populating the table to avoid it interfering with insertion order. ui->table_Results->setSortingEnabled(false); if (ui->comboBox_Search->findText(species) < 0) return; // Not a species name, no need to search wild encounter data. const QList results = this->resultsCache.value(species, search(species)); if (results.isEmpty()) { static const RowData noResults = { .groupName = QStringLiteral("Species not found."), .fieldName = QStringLiteral("--"), .levelRange = QStringLiteral("--"), .chance = QStringLiteral("--"), }; addTableEntry(noResults); } else { for (const auto &entry : results) { addTableEntry(entry); } } // TODO: This does a lexical sort... We might need custom item delegates to get proper numerical sorting in this table. ui->table_Results->setSortingEnabled(true); this->resultsCache.insert(species, results); } // Double-clicking row data opens the corresponding map/table on the Wild Pokémon tab. void WildMonSearch::cellDoubleClicked(int row, int) { auto groupItem = ui->table_Results->item(row, ResultsColumn::Group); auto fieldItem = ui->table_Results->item(row, ResultsColumn::Field); if (!groupItem || !fieldItem) return; const QString mapName = groupItem->data(ResultsDataRole::MapName).toString(); if (mapName.isEmpty()) return; emit openWildMonTableRequested(mapName, groupItem->text(), fieldItem->text()); }