From 6e814cbb8f3ede208952e161059f10f9a4c5168c Mon Sep 17 00:00:00 2001 From: "Admiral H. Curtiss" Date: Thu, 28 Oct 2021 02:00:38 +0200 Subject: [PATCH] Qt/CheatSearchWidget: Add a checkbox to force parsing a value as hexadecimal. --- Source/Core/Core/CheatSearch.cpp | 31 +++++++++++++++++---- Source/Core/Core/CheatSearch.h | 10 +++++-- Source/Core/DolphinQt/CheatSearchWidget.cpp | 20 ++++++++----- Source/Core/DolphinQt/CheatSearchWidget.h | 3 +- 4 files changed, 49 insertions(+), 15 deletions(-) diff --git a/Source/Core/Core/CheatSearch.cpp b/Source/Core/Core/CheatSearch.cpp index 9710f31624..66882911ba 100644 --- a/Source/Core/Core/CheatSearch.cpp +++ b/Source/Core/Core/CheatSearch.cpp @@ -340,22 +340,31 @@ void Cheats::CheatSearchSession::SetFilterType(FilterType filter_type) } template -static std::optional ParseValue(const std::string& str) +static std::optional ParseValue(const std::string& str, bool force_parse_as_hex) { if (str.empty()) return std::nullopt; T tmp; - if (TryParse(str, &tmp)) - return tmp; + if constexpr (std::is_integral_v) + { + if (TryParse(str, &tmp, force_parse_as_hex ? 16 : 0)) + return tmp; + } + else + { + if (TryParse(str, &tmp)) + return tmp; + } return std::nullopt; } template -bool Cheats::CheatSearchSession::SetValueFromString(const std::string& value_as_string) +bool Cheats::CheatSearchSession::SetValueFromString(const std::string& value_as_string, + bool force_parse_as_hex) { - m_value = ParseValue(value_as_string); + m_value = ParseValue(value_as_string, force_parse_as_hex); return m_value.has_value(); } @@ -498,6 +507,18 @@ bool Cheats::CheatSearchSession::GetAligned() return m_aligned; } +template +bool Cheats::CheatSearchSession::IsIntegerType() const +{ + return std::is_integral_v; +} + +template +bool Cheats::CheatSearchSession::IsFloatingType() const +{ + return std::is_floating_point_v; +} + template size_t Cheats::CheatSearchSession::GetResultCount() const { diff --git a/Source/Core/Core/CheatSearch.h b/Source/Core/Core/CheatSearch.h index 5b777f50f8..b03a7f8adc 100644 --- a/Source/Core/Core/CheatSearch.h +++ b/Source/Core/Core/CheatSearch.h @@ -132,7 +132,7 @@ public: virtual void SetFilterType(FilterType filter_type) = 0; // Set the value of the CompareAgainstSpecificValue filter used by subsequent searches. - virtual bool SetValueFromString(const std::string& value_as_string) = 0; + virtual bool SetValueFromString(const std::string& value_as_string, bool force_parse_as_hex) = 0; // Resets the search results, causing the next search to act as a new search. virtual void ResetResults() = 0; @@ -146,6 +146,9 @@ public: virtual DataType GetDataType() = 0; virtual bool GetAligned() = 0; + virtual bool IsIntegerType() const = 0; + virtual bool IsFloatingType() const = 0; + virtual size_t GetResultCount() const = 0; virtual size_t GetValidValueCount() const = 0; virtual u32 GetResultAddress(size_t index) const = 0; @@ -178,7 +181,7 @@ public: void SetCompareType(CompareType compare_type) override; void SetFilterType(FilterType filter_type) override; - bool SetValueFromString(const std::string& value_as_string) override; + bool SetValueFromString(const std::string& value_as_string, bool force_parse_as_hex) override; void ResetResults() override; SearchErrorCode RunSearch() override; @@ -189,6 +192,9 @@ public: DataType GetDataType() override; bool GetAligned() override; + bool IsIntegerType() const override; + bool IsFloatingType() const override; + size_t GetResultCount() const override; size_t GetValidValueCount() const override; u32 GetResultAddress(size_t index) const override; diff --git a/Source/Core/DolphinQt/CheatSearchWidget.cpp b/Source/Core/DolphinQt/CheatSearchWidget.cpp index eed1c2a058..07409c6ad5 100644 --- a/Source/Core/DolphinQt/CheatSearchWidget.cpp +++ b/Source/Core/DolphinQt/CheatSearchWidget.cpp @@ -57,6 +57,7 @@ CheatSearchWidget::CheatSearchWidget(std::unique_ptrsetText(tr("%1, %2, %3, %4").arg(ranges).arg(space).arg(type).arg(aligned)); } - auto* value_layout = new QHBoxLayout(); - // i18n: This label is followed by a dropdown where the user can select things like "is equal to" // or "is less than or equal to", followed by another dropdown where the user can select "any // value", "last value", or "this value:". These three UI elements are intended to form a sentence // together. Because the UI elements can't be reordered by a translation, you may have to give // up on the idea of having them form a sentence depending on the grammar of your target language. auto* instructions_label = new QLabel(tr("Keep addresses where value in memory")); - value_layout->addWidget(instructions_label); + auto* value_layout = new QHBoxLayout(); m_compare_type_dropdown = new QComboBox(); m_compare_type_dropdown->addItem(tr("is equal to"), QVariant::fromValue(Cheats::CompareType::Equal)); @@ -194,6 +193,9 @@ void CheatSearchWidget::CreateWidgets() m_given_value_text = new QLineEdit(); value_layout->addWidget(m_given_value_text); + m_parse_values_as_hex_checkbox = new QCheckBox(tr("Parse as Hex")); + value_layout->addWidget(m_parse_values_as_hex_checkbox); + auto* button_layout = new QHBoxLayout(); m_next_scan_button = new QPushButton(tr("Search and Filter")); button_layout->addWidget(m_next_scan_button); @@ -212,6 +214,7 @@ void CheatSearchWidget::CreateWidgets() QVBoxLayout* layout = new QVBoxLayout(); layout->addWidget(session_info_label); + layout->addWidget(instructions_label); layout->addLayout(value_layout); layout->addLayout(button_layout); layout->addWidget(m_display_values_in_hex_checkbox); @@ -234,7 +237,7 @@ void CheatSearchWidget::ConnectWidgets() connect(m_value_source_dropdown, &QComboBox::currentTextChanged, this, &CheatSearchWidget::OnValueSourceChanged); connect(m_display_values_in_hex_checkbox, &QCheckBox::toggled, this, - &CheatSearchWidget::OnHexCheckboxStateChanged); + &CheatSearchWidget::OnDisplayHexCheckboxStateChanged); } void CheatSearchWidget::OnNextScanClicked() @@ -253,7 +256,8 @@ void CheatSearchWidget::OnNextScanClicked() m_session->SetCompareType(m_compare_type_dropdown->currentData().value()); if (filter_type == Cheats::FilterType::CompareAgainstSpecificValue) { - if (!m_session->SetValueFromString(m_given_value_text->text().toStdString())) + if (!m_session->SetValueFromString(m_given_value_text->text().toStdString(), + m_parse_values_as_hex_checkbox->isChecked())) { m_info_label_1->setText(tr("Failed to parse given value into target data type.")); return; @@ -431,10 +435,12 @@ void CheatSearchWidget::OnAddressTableContextMenu() void CheatSearchWidget::OnValueSourceChanged() { const auto filter_type = m_value_source_dropdown->currentData().value(); - m_given_value_text->setEnabled(filter_type == Cheats::FilterType::CompareAgainstSpecificValue); + const bool is_value_search = filter_type == Cheats::FilterType::CompareAgainstSpecificValue; + m_given_value_text->setEnabled(is_value_search); + m_parse_values_as_hex_checkbox->setEnabled(is_value_search && m_session->IsIntegerType()); } -void CheatSearchWidget::OnHexCheckboxStateChanged() +void CheatSearchWidget::OnDisplayHexCheckboxStateChanged() { if (!m_session->WasFirstSearchDone()) return; diff --git a/Source/Core/DolphinQt/CheatSearchWidget.h b/Source/Core/DolphinQt/CheatSearchWidget.h index 74ee2fc2d7..9fa1581247 100644 --- a/Source/Core/DolphinQt/CheatSearchWidget.h +++ b/Source/Core/DolphinQt/CheatSearchWidget.h @@ -52,7 +52,7 @@ private: void OnAddressTableItemChanged(QTableWidgetItem* item); void OnAddressTableContextMenu(); void OnValueSourceChanged(); - void OnHexCheckboxStateChanged(); + void OnDisplayHexCheckboxStateChanged(); bool RefreshValues(); void UpdateGuiTable(); @@ -75,6 +75,7 @@ private: QPushButton* m_next_scan_button; QPushButton* m_refresh_values_button; QPushButton* m_reset_button; + QCheckBox* m_parse_values_as_hex_checkbox; QCheckBox* m_display_values_in_hex_checkbox; QTableWidget* m_address_table; };