diff options
Diffstat (limited to 'src/yuzu')
| -rw-r--r-- | src/yuzu/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/yuzu/about_dialog.cpp | 8 | ||||
| -rw-r--r-- | src/yuzu/applets/profile_select.cpp | 4 | ||||
| -rw-r--r-- | src/yuzu/bootmanager.cpp | 1 | ||||
| -rw-r--r-- | src/yuzu/debugger/graphics/graphics_breakpoints.cpp | 2 | ||||
| -rw-r--r-- | src/yuzu/debugger/profiler.cpp | 4 | ||||
| -rw-r--r-- | src/yuzu/debugger/wait_tree.cpp | 39 | ||||
| -rw-r--r-- | src/yuzu/main.cpp | 25 | ||||
| -rw-r--r-- | src/yuzu/main.h | 1 | ||||
| -rw-r--r-- | src/yuzu/util/spinbox.cpp | 278 | ||||
| -rw-r--r-- | src/yuzu/util/spinbox.h | 86 | 
11 files changed, 50 insertions, 400 deletions
| diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt index 5138bd9a3..7e883991a 100644 --- a/src/yuzu/CMakeLists.txt +++ b/src/yuzu/CMakeLists.txt @@ -82,8 +82,6 @@ add_executable(yuzu      util/limitable_input_dialog.h      util/sequence_dialog/sequence_dialog.cpp      util/sequence_dialog/sequence_dialog.h -    util/spinbox.cpp -    util/spinbox.h      util/util.cpp      util/util.h      compatdb.cpp diff --git a/src/yuzu/about_dialog.cpp b/src/yuzu/about_dialog.cpp index 3efa65a38..d39b3f07a 100644 --- a/src/yuzu/about_dialog.cpp +++ b/src/yuzu/about_dialog.cpp @@ -9,10 +9,10 @@  AboutDialog::AboutDialog(QWidget* parent) : QDialog(parent), ui(new Ui::AboutDialog) {      ui->setupUi(this); -    ui->labelLogo->setPixmap(QIcon::fromTheme("yuzu").pixmap(200)); -    ui->labelBuildInfo->setText( -        ui->labelBuildInfo->text().arg(Common::g_build_fullname, Common::g_scm_branch, -                                       Common::g_scm_desc, QString(Common::g_build_date).left(10))); +    ui->labelLogo->setPixmap(QIcon::fromTheme(QStringLiteral("yuzu")).pixmap(200)); +    ui->labelBuildInfo->setText(ui->labelBuildInfo->text().arg( +        QString::fromUtf8(Common::g_build_fullname), QString::fromUtf8(Common::g_scm_branch), +        QString::fromUtf8(Common::g_scm_desc), QString::fromUtf8(Common::g_build_date).left(10)));  }  AboutDialog::~AboutDialog() = default; diff --git a/src/yuzu/applets/profile_select.cpp b/src/yuzu/applets/profile_select.cpp index 743b24d76..7fbc9deeb 100644 --- a/src/yuzu/applets/profile_select.cpp +++ b/src/yuzu/applets/profile_select.cpp @@ -84,10 +84,10 @@ QtProfileSelectionDialog::QtProfileSelectionDialog(QWidget* parent)      tree_view->setContextMenuPolicy(Qt::NoContextMenu);      item_model->insertColumns(0, 1); -    item_model->setHeaderData(0, Qt::Horizontal, "Users"); +    item_model->setHeaderData(0, Qt::Horizontal, tr("Users"));      // We must register all custom types with the Qt Automoc system so that we are able to use it -    // with signals/slots. In this case, QList falls under the umbrells of custom types. +    // with signals/slots. In this case, QList falls under the umbrella of custom types.      qRegisterMetaType<QList<QStandardItem*>>("QList<QStandardItem*>");      layout->setContentsMargins(0, 0, 0, 0); diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp index 5c98636c5..810954b36 100644 --- a/src/yuzu/bootmanager.cpp +++ b/src/yuzu/bootmanager.cpp @@ -379,6 +379,7 @@ void GRenderWindow::InitRenderTarget() {      fmt.setVersion(4, 3);      if (Settings::values.use_compatibility_profile) {          fmt.setProfile(QSurfaceFormat::CompatibilityProfile); +        fmt.setOption(QSurfaceFormat::FormatOption::DeprecatedFunctions);      } else {          fmt.setProfile(QSurfaceFormat::CoreProfile);      } diff --git a/src/yuzu/debugger/graphics/graphics_breakpoints.cpp b/src/yuzu/debugger/graphics/graphics_breakpoints.cpp index 67ed0ba6d..1c80082a4 100644 --- a/src/yuzu/debugger/graphics/graphics_breakpoints.cpp +++ b/src/yuzu/debugger/graphics/graphics_breakpoints.cpp @@ -135,7 +135,7 @@ GraphicsBreakPointsWidget::GraphicsBreakPointsWidget(      std::shared_ptr<Tegra::DebugContext> debug_context, QWidget* parent)      : QDockWidget(tr("Maxwell Breakpoints"), parent), Tegra::DebugContext::BreakPointObserver(                                                            debug_context) { -    setObjectName("TegraBreakPointsWidget"); +    setObjectName(QStringLiteral("TegraBreakPointsWidget"));      status_text = new QLabel(tr("Emulation running"));      resume_button = new QPushButton(tr("Resume")); diff --git a/src/yuzu/debugger/profiler.cpp b/src/yuzu/debugger/profiler.cpp index 86e03e46d..f594ef076 100644 --- a/src/yuzu/debugger/profiler.cpp +++ b/src/yuzu/debugger/profiler.cpp @@ -47,7 +47,7 @@ private:  #endif  MicroProfileDialog::MicroProfileDialog(QWidget* parent) : QWidget(parent, Qt::Dialog) { -    setObjectName("MicroProfile"); +    setObjectName(QStringLiteral("MicroProfile"));      setWindowTitle(tr("MicroProfile"));      resize(1000, 600);      // Remove the "?" button from the titlebar and enable the maximize button @@ -191,7 +191,7 @@ void MicroProfileDrawText(int x, int y, u32 hex_color, const char* text, u32 tex      for (u32 i = 0; i < text_length; ++i) {          // Position the text baseline 1 pixel above the bottom of the text cell, this gives nice          // vertical alignment of text for a wide range of tested fonts. -        mp_painter->drawText(x, y + MICROPROFILE_TEXT_HEIGHT - 2, QChar(text[i])); +        mp_painter->drawText(x, y + MICROPROFILE_TEXT_HEIGHT - 2, QString{QLatin1Char{text[i]}});          x += MICROPROFILE_TEXT_WIDTH + 1;      }  } diff --git a/src/yuzu/debugger/wait_tree.cpp b/src/yuzu/debugger/wait_tree.cpp index 85b095688..cd8180f8b 100644 --- a/src/yuzu/debugger/wait_tree.cpp +++ b/src/yuzu/debugger/wait_tree.cpp @@ -91,19 +91,19 @@ WaitTreeMutexInfo::WaitTreeMutexInfo(VAddr mutex_address, const Kernel::HandleTa  WaitTreeMutexInfo::~WaitTreeMutexInfo() = default;  QString WaitTreeMutexInfo::GetText() const { -    return tr("waiting for mutex 0x%1").arg(mutex_address, 16, 16, QLatin1Char('0')); +    return tr("waiting for mutex 0x%1").arg(mutex_address, 16, 16, QLatin1Char{'0'});  }  std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeMutexInfo::GetChildren() const { -    std::vector<std::unique_ptr<WaitTreeItem>> list; - -    bool has_waiters = (mutex_value & Kernel::Mutex::MutexHasWaitersFlag) != 0; +    const bool has_waiters = (mutex_value & Kernel::Mutex::MutexHasWaitersFlag) != 0; +    std::vector<std::unique_ptr<WaitTreeItem>> list;      list.push_back(std::make_unique<WaitTreeText>(tr("has waiters: %1").arg(has_waiters)));      list.push_back(std::make_unique<WaitTreeText>( -        tr("owner handle: 0x%1").arg(owner_handle, 8, 16, QLatin1Char('0')))); -    if (owner != nullptr) +        tr("owner handle: 0x%1").arg(owner_handle, 8, 16, QLatin1Char{'0'}))); +    if (owner != nullptr) {          list.push_back(std::make_unique<WaitTreeThread>(*owner)); +    }      return list;  } @@ -121,11 +121,14 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeCallstack::GetChildren() cons      u64 base_pointer = thread.GetContext().cpu_registers[BaseRegister];      while (base_pointer != 0) { -        u64 lr = Memory::Read64(base_pointer + sizeof(u64)); -        if (lr == 0) +        const u64 lr = Memory::Read64(base_pointer + sizeof(u64)); +        if (lr == 0) {              break; -        list.push_back( -            std::make_unique<WaitTreeText>(tr("0x%1").arg(lr - sizeof(u32), 16, 16, QChar('0')))); +        } + +        list.push_back(std::make_unique<WaitTreeText>( +            tr("0x%1").arg(lr - sizeof(u32), 16, 16, QLatin1Char{'0'}))); +          base_pointer = Memory::Read64(base_pointer);      } @@ -174,10 +177,10 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeWaitObject::GetChildren() con  QString WaitTreeWaitObject::GetResetTypeQString(Kernel::ResetType reset_type) {      switch (reset_type) { -    case Kernel::ResetType::OneShot: -        return tr("one shot"); -    case Kernel::ResetType::Sticky: -        return tr("sticky"); +    case Kernel::ResetType::Automatic: +        return tr("automatic reset"); +    case Kernel::ResetType::Manual: +        return tr("manual reset");      }      UNREACHABLE();      return {}; @@ -249,9 +252,9 @@ QString WaitTreeThread::GetText() const {      const auto& context = thread.GetContext();      const QString pc_info = tr(" PC = 0x%1 LR = 0x%2") -                                .arg(context.pc, 8, 16, QLatin1Char('0')) -                                .arg(context.cpu_registers[30], 8, 16, QLatin1Char('0')); -    return WaitTreeWaitObject::GetText() + pc_info + " (" + status + ") "; +                                .arg(context.pc, 8, 16, QLatin1Char{'0'}) +                                .arg(context.cpu_registers[30], 8, 16, QLatin1Char{'0'}); +    return QStringLiteral("%1%2 (%3) ").arg(WaitTreeWaitObject::GetText(), pc_info, status);  }  QColor WaitTreeThread::GetColor() const { @@ -424,7 +427,7 @@ void WaitTreeModel::InitItems() {  }  WaitTreeWidget::WaitTreeWidget(QWidget* parent) : QDockWidget(tr("Wait Tree"), parent) { -    setObjectName("WaitTreeWidget"); +    setObjectName(QStringLiteral("WaitTreeWidget"));      view = new QTreeView(this);      view->setHeaderHidden(true);      setWidget(view); diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index e33e3aaaf..a59abf6e8 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -198,11 +198,11 @@ GMainWindow::GMainWindow()      ConnectMenuEvents();      ConnectWidgetEvents(); +      LOG_INFO(Frontend, "yuzu Version: {} | {}-{}", Common::g_build_fullname, Common::g_scm_branch,               Common::g_scm_desc); +    UpdateWindowTitle(); -    setWindowTitle(QString("yuzu %1| %2-%3") -                       .arg(Common::g_build_fullname, Common::g_scm_branch, Common::g_scm_desc));      show();      Core::System::GetInstance().SetContentProvider( @@ -936,9 +936,7 @@ void GMainWindow::BootGame(const QString& filename) {              title_name = FileUtil::GetFilename(filename.toStdString());      } -    setWindowTitle(QString("yuzu %1| %4 | %2-%3") -                       .arg(Common::g_build_fullname, Common::g_scm_branch, Common::g_scm_desc, -                            QString::fromStdString(title_name))); +    UpdateWindowTitle(QString::fromStdString(title_name));      loading_screen->Prepare(Core::System::GetInstance().GetAppLoader());      loading_screen->show(); @@ -979,8 +977,8 @@ void GMainWindow::ShutdownGame() {      loading_screen->Clear();      game_list->show();      game_list->setFilterFocus(); -    setWindowTitle(QString("yuzu %1| %2-%3") -                       .arg(Common::g_build_fullname, Common::g_scm_branch, Common::g_scm_desc)); + +    UpdateWindowTitle();      // Disable status bar updates      status_bar_update_timer.stop(); @@ -1767,6 +1765,19 @@ void GMainWindow::OnCaptureScreenshot() {      OnStartGame();  } +void GMainWindow::UpdateWindowTitle(const QString& title_name) { +    const QString full_name = QString::fromUtf8(Common::g_build_fullname); +    const QString branch_name = QString::fromUtf8(Common::g_scm_branch); +    const QString description = QString::fromUtf8(Common::g_scm_desc); + +    if (title_name.isEmpty()) { +        setWindowTitle(QStringLiteral("yuzu %1| %2-%3").arg(full_name, branch_name, description)); +    } else { +        setWindowTitle(QStringLiteral("yuzu %1| %4 | %2-%3") +                           .arg(full_name, branch_name, description, title_name)); +    } +} +  void GMainWindow::UpdateStatusBar() {      if (emu_thread == nullptr) {          status_bar_update_timer.stop(); diff --git a/src/yuzu/main.h b/src/yuzu/main.h index fb2a193cb..7bf82e665 100644 --- a/src/yuzu/main.h +++ b/src/yuzu/main.h @@ -209,6 +209,7 @@ private slots:  private:      std::optional<u64> SelectRomFSDumpTarget(const FileSys::ContentProvider&, u64 program_id); +    void UpdateWindowTitle(const QString& title_name = {});      void UpdateStatusBar();      Ui::MainWindow ui; diff --git a/src/yuzu/util/spinbox.cpp b/src/yuzu/util/spinbox.cpp deleted file mode 100644 index 14ef1e884..000000000 --- a/src/yuzu/util/spinbox.cpp +++ /dev/null @@ -1,278 +0,0 @@ -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -// Copyright 2014 Tony Wasserka -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -//     * Redistributions of source code must retain the above copyright -//       notice, this list of conditions and the following disclaimer. -//     * Redistributions in binary form must reproduce the above copyright -//       notice, this list of conditions and the following disclaimer in the -//       documentation and/or other materials provided with the distribution. -//     * Neither the name of the owner nor the names of its contributors may -//       be used to endorse or promote products derived from this software -//       without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include <cstdlib> -#include <QLineEdit> -#include <QRegExpValidator> -#include "common/assert.h" -#include "yuzu/util/spinbox.h" - -CSpinBox::CSpinBox(QWidget* parent) -    : QAbstractSpinBox(parent), min_value(-100), max_value(100), value(0), base(10), num_digits(0) { -    // TODO: Might be nice to not immediately call the slot. -    //       Think of an address that is being replaced by a different one, in which case a lot -    //       invalid intermediate addresses would be read from during editing. -    connect(lineEdit(), &QLineEdit::textEdited, this, &CSpinBox::OnEditingFinished); - -    UpdateText(); -} - -void CSpinBox::SetValue(qint64 val) { -    auto old_value = value; -    value = std::max(std::min(val, max_value), min_value); - -    if (old_value != value) { -        UpdateText(); -        emit ValueChanged(value); -    } -} - -void CSpinBox::SetRange(qint64 min, qint64 max) { -    min_value = min; -    max_value = max; - -    SetValue(value); -    UpdateText(); -} - -void CSpinBox::stepBy(int steps) { -    auto new_value = value; -    // Scale number of steps by the currently selected digit -    // TODO: Move this code elsewhere and enable it. -    // TODO: Support for num_digits==0, too -    // TODO: Support base!=16, too -    // TODO: Make the cursor not jump back to the end of the line... -    /*if (base == 16 && num_digits > 0) { -        int digit = num_digits - (lineEdit()->cursorPosition() - prefix.length()) - 1; -        digit = std::max(0, std::min(digit, num_digits - 1)); -        steps <<= digit * 4; -    }*/ - -    // Increment "new_value" by "steps", and perform annoying overflow checks, too. -    if (steps < 0 && new_value + steps > new_value) { -        new_value = std::numeric_limits<qint64>::min(); -    } else if (steps > 0 && new_value + steps < new_value) { -        new_value = std::numeric_limits<qint64>::max(); -    } else { -        new_value += steps; -    } - -    SetValue(new_value); -    UpdateText(); -} - -QAbstractSpinBox::StepEnabled CSpinBox::stepEnabled() const { -    StepEnabled ret = StepNone; - -    if (value > min_value) -        ret |= StepDownEnabled; - -    if (value < max_value) -        ret |= StepUpEnabled; - -    return ret; -} - -void CSpinBox::SetBase(int base) { -    this->base = base; - -    UpdateText(); -} - -void CSpinBox::SetNumDigits(int num_digits) { -    this->num_digits = num_digits; - -    UpdateText(); -} - -void CSpinBox::SetPrefix(const QString& prefix) { -    this->prefix = prefix; - -    UpdateText(); -} - -void CSpinBox::SetSuffix(const QString& suffix) { -    this->suffix = suffix; - -    UpdateText(); -} - -static QString StringToInputMask(const QString& input) { -    QString mask = input; - -    // ... replace any special characters by their escaped counterparts ... -    mask.replace("\\", "\\\\"); -    mask.replace("A", "\\A"); -    mask.replace("a", "\\a"); -    mask.replace("N", "\\N"); -    mask.replace("n", "\\n"); -    mask.replace("X", "\\X"); -    mask.replace("x", "\\x"); -    mask.replace("9", "\\9"); -    mask.replace("0", "\\0"); -    mask.replace("D", "\\D"); -    mask.replace("d", "\\d"); -    mask.replace("#", "\\#"); -    mask.replace("H", "\\H"); -    mask.replace("h", "\\h"); -    mask.replace("B", "\\B"); -    mask.replace("b", "\\b"); -    mask.replace(">", "\\>"); -    mask.replace("<", "\\<"); -    mask.replace("!", "\\!"); - -    return mask; -} - -void CSpinBox::UpdateText() { -    // If a fixed number of digits is used, we put the line edit in insertion mode by setting an -    // input mask. -    QString mask; -    if (num_digits != 0) { -        mask += StringToInputMask(prefix); - -        // For base 10 and negative range, demand a single sign character -        if (HasSign()) -            mask += "X"; // identified as "-" or "+" in the validator - -        // Uppercase digits greater than 9. -        mask += ">"; - -        // Match num_digits digits -        // Digits irrelevant to the chosen number base are filtered in the validator -        mask += QString("H").repeated(std::max(num_digits, 1)); - -        // Switch off case conversion -        mask += "!"; - -        mask += StringToInputMask(suffix); -    } -    lineEdit()->setInputMask(mask); - -    // Set new text without changing the cursor position. This will cause the cursor to briefly -    // appear at the end of the line and then to jump back to its original position. That's -    // a bit ugly, but better than having setText() move the cursor permanently all the time. -    int cursor_position = lineEdit()->cursorPosition(); -    lineEdit()->setText(TextFromValue()); -    lineEdit()->setCursorPosition(cursor_position); -} - -QString CSpinBox::TextFromValue() { -    return prefix + QString(HasSign() ? ((value < 0) ? "-" : "+") : "") + -           QString("%1").arg(std::abs(value), num_digits, base, QLatin1Char('0')).toUpper() + -           suffix; -} - -qint64 CSpinBox::ValueFromText() { -    unsigned strpos = prefix.length(); - -    QString num_string = text().mid(strpos, text().length() - strpos - suffix.length()); -    return num_string.toLongLong(nullptr, base); -} - -bool CSpinBox::HasSign() const { -    return base == 10 && min_value < 0; -} - -void CSpinBox::OnEditingFinished() { -    // Only update for valid input -    QString input = lineEdit()->text(); -    int pos = 0; -    if (QValidator::Acceptable == validate(input, pos)) -        SetValue(ValueFromText()); -} - -QValidator::State CSpinBox::validate(QString& input, int& pos) const { -    if (!prefix.isEmpty() && input.left(prefix.length()) != prefix) -        return QValidator::Invalid; - -    int strpos = prefix.length(); - -    // Empty "numbers" allowed as intermediate values -    if (strpos >= input.length() - HasSign() - suffix.length()) -        return QValidator::Intermediate; - -    DEBUG_ASSERT(base <= 10 || base == 16); -    QString regexp; - -    // Demand sign character for negative ranges -    if (HasSign()) -        regexp += "[+\\-]"; - -    // Match digits corresponding to the chosen number base. -    regexp += QString("[0-%1").arg(std::min(base, 9)); -    if (base == 16) { -        regexp += "a-fA-F"; -    } -    regexp += "]"; - -    // Specify number of digits -    if (num_digits > 0) { -        regexp += QString("{%1}").arg(num_digits); -    } else { -        regexp += "+"; -    } - -    // Match string -    QRegExp num_regexp(regexp); -    int num_pos = strpos; -    QString sub_input = input.mid(strpos, input.length() - strpos - suffix.length()); - -    if (!num_regexp.exactMatch(sub_input) && num_regexp.matchedLength() == 0) -        return QValidator::Invalid; - -    sub_input = sub_input.left(num_regexp.matchedLength()); -    bool ok; -    qint64 val = sub_input.toLongLong(&ok, base); - -    if (!ok) -        return QValidator::Invalid; - -    // Outside boundaries => don't accept -    if (val < min_value || val > max_value) -        return QValidator::Invalid; - -    // Make sure we are actually at the end of this string... -    strpos += num_regexp.matchedLength(); - -    if (!suffix.isEmpty() && input.mid(strpos) != suffix) { -        return QValidator::Invalid; -    } else { -        strpos += suffix.length(); -    } - -    if (strpos != input.length()) -        return QValidator::Invalid; - -    // At this point we can say for sure that the input is fine. Let's fix it up a bit though -    input.replace(num_pos, sub_input.length(), sub_input.toUpper()); - -    return QValidator::Acceptable; -} diff --git a/src/yuzu/util/spinbox.h b/src/yuzu/util/spinbox.h deleted file mode 100644 index 2fa1db3a4..000000000 --- a/src/yuzu/util/spinbox.h +++ /dev/null @@ -1,86 +0,0 @@ -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -// Copyright 2014 Tony Wasserka -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -//     * Redistributions of source code must retain the above copyright -//       notice, this list of conditions and the following disclaimer. -//     * Redistributions in binary form must reproduce the above copyright -//       notice, this list of conditions and the following disclaimer in the -//       documentation and/or other materials provided with the distribution. -//     * Neither the name of the owner nor the names of its contributors may -//       be used to endorse or promote products derived from this software -//       without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#pragma once - -#include <QAbstractSpinBox> -#include <QtGlobal> - -class QVariant; - -/** - * A custom spin box widget with enhanced functionality over Qt's QSpinBox - */ -class CSpinBox : public QAbstractSpinBox { -    Q_OBJECT - -public: -    explicit CSpinBox(QWidget* parent = nullptr); - -    void stepBy(int steps) override; -    StepEnabled stepEnabled() const override; - -    void SetValue(qint64 val); - -    void SetRange(qint64 min, qint64 max); - -    void SetBase(int base); - -    void SetPrefix(const QString& prefix); -    void SetSuffix(const QString& suffix); - -    void SetNumDigits(int num_digits); - -    QValidator::State validate(QString& input, int& pos) const override; - -signals: -    void ValueChanged(qint64 val); - -private slots: -    void OnEditingFinished(); - -private: -    void UpdateText(); - -    bool HasSign() const; - -    QString TextFromValue(); -    qint64 ValueFromText(); - -    qint64 min_value, max_value; - -    qint64 value; - -    QString prefix, suffix; - -    int base; - -    int num_digits; -}; | 
