From 32b3ed0a1362a4b0798ad71fac3450fb77cb7e41 Mon Sep 17 00:00:00 2001 From: Thomas Groman Date: Thu, 19 Sep 2019 00:41:48 -0700 Subject: merged from 0.6.7 codebase --- application/widgets/Common.cpp | 42 +- application/widgets/Common.h | 2 +- application/widgets/CustomCommands.cpp | 34 +- application/widgets/CustomCommands.h | 20 +- application/widgets/CustomCommands.ui | 12 + application/widgets/FocusLineEdit.cpp | 22 +- application/widgets/FocusLineEdit.h | 16 +- application/widgets/IconLabel.cpp | 40 +- application/widgets/IconLabel.h | 16 +- application/widgets/JavaSettingsWidget.cpp | 654 ++++++++++++------------ application/widgets/JavaSettingsWidget.h | 122 ++--- application/widgets/LabeledToolButton.cpp | 104 ++-- application/widgets/LabeledToolButton.h | 22 +- application/widgets/LanguageSelectionWidget.cpp | 68 +++ application/widgets/LanguageSelectionWidget.h | 41 ++ application/widgets/LineSeparator.cpp | 30 +- application/widgets/LineSeparator.h | 14 +- application/widgets/LogView.cpp | 186 +++---- application/widgets/LogView.h | 38 +- application/widgets/MCModInfoFrame.cpp | 212 ++++---- application/widgets/MCModInfoFrame.h | 30 +- application/widgets/ModListView.cpp | 76 +-- application/widgets/ModListView.h | 10 +- application/widgets/PageContainer.cpp | 310 +++++------ application/widgets/PageContainer.h | 81 +-- application/widgets/PageContainer_p.h | 158 +++--- application/widgets/ProgressWidget.cpp | 80 +-- application/widgets/ProgressWidget.h | 22 +- application/widgets/ServerStatus.cpp | 214 ++++---- application/widgets/ServerStatus.h | 34 +- application/widgets/VersionListView.cpp | 185 +++---- application/widgets/VersionListView.h | 49 +- application/widgets/VersionSelectWidget.cpp | 213 ++++---- application/widgets/VersionSelectWidget.h | 70 +-- application/widgets/WideBar.cpp | 116 +++++ application/widgets/WideBar.h | 26 + 36 files changed, 1812 insertions(+), 1557 deletions(-) create mode 100644 application/widgets/LanguageSelectionWidget.cpp create mode 100644 application/widgets/LanguageSelectionWidget.h create mode 100644 application/widgets/WideBar.cpp create mode 100644 application/widgets/WideBar.h (limited to 'application/widgets') diff --git a/application/widgets/Common.cpp b/application/widgets/Common.cpp index 9b730d6c..f72f3596 100644 --- a/application/widgets/Common.cpp +++ b/application/widgets/Common.cpp @@ -2,26 +2,26 @@ // Origin: Qt QStringList viewItemTextLayout(QTextLayout &textLayout, int lineWidth, qreal &height, - qreal &widthUsed) + qreal &widthUsed) { - QStringList lines; - height = 0; - widthUsed = 0; - textLayout.beginLayout(); - QString str = textLayout.text(); - while (true) - { - QTextLine line = textLayout.createLine(); - if (!line.isValid()) - break; - if (line.textLength() == 0) - break; - line.setLineWidth(lineWidth); - line.setPosition(QPointF(0, height)); - height += line.height(); - lines.append(str.mid(line.textStart(), line.textLength())); - widthUsed = qMax(widthUsed, line.naturalTextWidth()); - } - textLayout.endLayout(); - return lines; + QStringList lines; + height = 0; + widthUsed = 0; + textLayout.beginLayout(); + QString str = textLayout.text(); + while (true) + { + QTextLine line = textLayout.createLine(); + if (!line.isValid()) + break; + if (line.textLength() == 0) + break; + line.setLineWidth(lineWidth); + line.setPosition(QPointF(0, height)); + height += line.height(); + lines.append(str.mid(line.textStart(), line.textLength())); + widthUsed = qMax(widthUsed, line.naturalTextWidth()); + } + textLayout.endLayout(); + return lines; } diff --git a/application/widgets/Common.h b/application/widgets/Common.h index fc46e08f..b3fbe1a0 100644 --- a/application/widgets/Common.h +++ b/application/widgets/Common.h @@ -3,4 +3,4 @@ #include QStringList viewItemTextLayout(QTextLayout &textLayout, int lineWidth, qreal &height, - qreal &widthUsed); \ No newline at end of file + qreal &widthUsed); \ No newline at end of file diff --git a/application/widgets/CustomCommands.cpp b/application/widgets/CustomCommands.cpp index 9f11e344..9e7673fd 100644 --- a/application/widgets/CustomCommands.cpp +++ b/application/widgets/CustomCommands.cpp @@ -6,43 +6,43 @@ CustomCommands::~CustomCommands() } CustomCommands::CustomCommands(QWidget* parent): - QWidget(parent), - ui(new Ui::CustomCommands) + QWidget(parent), + ui(new Ui::CustomCommands) { - ui->setupUi(this); + ui->setupUi(this); } void CustomCommands::initialize(bool checkable, bool checked, const QString& prelaunch, const QString& wrapper, const QString& postexit) { - ui->customCommandsGroupBox->setCheckable(checkable); - if(checkable) - { - ui->customCommandsGroupBox->setChecked(checked); - } - ui->preLaunchCmdTextBox->setText(prelaunch); - ui->wrapperCmdTextBox->setText(wrapper); - ui->postExitCmdTextBox->setText(postexit); + ui->customCommandsGroupBox->setCheckable(checkable); + if(checkable) + { + ui->customCommandsGroupBox->setChecked(checked); + } + ui->preLaunchCmdTextBox->setText(prelaunch); + ui->wrapperCmdTextBox->setText(wrapper); + ui->postExitCmdTextBox->setText(postexit); } bool CustomCommands::checked() const { - if(!ui->customCommandsGroupBox->isCheckable()) - return true; - return ui->customCommandsGroupBox->isChecked(); + if(!ui->customCommandsGroupBox->isCheckable()) + return true; + return ui->customCommandsGroupBox->isChecked(); } QString CustomCommands::prelaunchCommand() const { - return ui->preLaunchCmdTextBox->text(); + return ui->preLaunchCmdTextBox->text(); } QString CustomCommands::wrapperCommand() const { - return ui->wrapperCmdTextBox->text(); + return ui->wrapperCmdTextBox->text(); } QString CustomCommands::postexitCommand() const { - return ui->postExitCmdTextBox->text(); + return ui->postExitCmdTextBox->text(); } diff --git a/application/widgets/CustomCommands.h b/application/widgets/CustomCommands.h index 2bc7cb1a..451b2cc0 100644 --- a/application/widgets/CustomCommands.h +++ b/application/widgets/CustomCommands.h @@ -1,4 +1,4 @@ -/* Copyright 2018-2018 MultiMC Contributors +/* Copyright 2018-2019 MultiMC Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,20 +24,20 @@ class CustomCommands; class CustomCommands : public QWidget { - Q_OBJECT + Q_OBJECT public: - explicit CustomCommands(QWidget *parent = 0); - ~CustomCommands(); - void initialize(bool checkable, bool checked, const QString & prelaunch, const QString & wrapper, const QString & postexit); + explicit CustomCommands(QWidget *parent = 0); + ~CustomCommands(); + void initialize(bool checkable, bool checked, const QString & prelaunch, const QString & wrapper, const QString & postexit); - bool checked() const; - QString prelaunchCommand() const; - QString wrapperCommand() const; - QString postexitCommand() const; + bool checked() const; + QString prelaunchCommand() const; + QString wrapperCommand() const; + QString postexitCommand() const; private: - Ui::CustomCommands *ui; + Ui::CustomCommands *ui; }; diff --git a/application/widgets/CustomCommands.ui b/application/widgets/CustomCommands.ui index d3bc86b8..c302fe39 100644 --- a/application/widgets/CustomCommands.ui +++ b/application/widgets/CustomCommands.ui @@ -14,6 +14,18 @@ Form + + 0 + + + 0 + + + 0 + + + 0 + diff --git a/application/widgets/FocusLineEdit.cpp b/application/widgets/FocusLineEdit.cpp index 139126c8..b272100c 100644 --- a/application/widgets/FocusLineEdit.cpp +++ b/application/widgets/FocusLineEdit.cpp @@ -3,23 +3,23 @@ FocusLineEdit::FocusLineEdit(QWidget *parent) : QLineEdit(parent) { - _selectOnMousePress = false; + _selectOnMousePress = false; } void FocusLineEdit::focusInEvent(QFocusEvent *e) { - QLineEdit::focusInEvent(e); - selectAll(); - _selectOnMousePress = true; + QLineEdit::focusInEvent(e); + selectAll(); + _selectOnMousePress = true; } void FocusLineEdit::mousePressEvent(QMouseEvent *me) { - QLineEdit::mousePressEvent(me); - if (_selectOnMousePress) - { - selectAll(); - _selectOnMousePress = false; - } - qDebug() << selectedText(); + QLineEdit::mousePressEvent(me); + if (_selectOnMousePress) + { + selectAll(); + _selectOnMousePress = false; + } + qDebug() << selectedText(); } diff --git a/application/widgets/FocusLineEdit.h b/application/widgets/FocusLineEdit.h index 6d1c78a8..71b4f140 100644 --- a/application/widgets/FocusLineEdit.h +++ b/application/widgets/FocusLineEdit.h @@ -2,16 +2,16 @@ class FocusLineEdit : public QLineEdit { - Q_OBJECT + Q_OBJECT public: - FocusLineEdit(QWidget *parent); - virtual ~FocusLineEdit() - { - } + FocusLineEdit(QWidget *parent); + virtual ~FocusLineEdit() + { + } protected: - void focusInEvent(QFocusEvent *e); - void mousePressEvent(QMouseEvent *me); + void focusInEvent(QFocusEvent *e); + void mousePressEvent(QMouseEvent *me); - bool _selectOnMousePress; + bool _selectOnMousePress; }; diff --git a/application/widgets/IconLabel.cpp b/application/widgets/IconLabel.cpp index 86c8a431..bf1c2358 100644 --- a/application/widgets/IconLabel.cpp +++ b/application/widgets/IconLabel.cpp @@ -7,37 +7,37 @@ #include IconLabel::IconLabel(QWidget *parent, QIcon icon, QSize size) - : QWidget(parent), m_size(size), m_icon(icon) + : QWidget(parent), m_size(size), m_icon(icon) { - setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); + setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); } QSize IconLabel::sizeHint() const { - return m_size; + return m_size; } void IconLabel::setIcon(QIcon icon) { - m_icon = icon; - update(); + m_icon = icon; + update(); } void IconLabel::paintEvent(QPaintEvent *) { - QPainter p(this); - QRect rect = contentsRect(); - int width = rect.width(); - int height = rect.height(); - if(width < height) - { - rect.setHeight(width); - rect.translate(0, (height - width) / 2); - } - else if (width > height) - { - rect.setWidth(height); - rect.translate((width - height) / 2, 0); - } - m_icon.paint(&p, rect); + QPainter p(this); + QRect rect = contentsRect(); + int width = rect.width(); + int height = rect.height(); + if(width < height) + { + rect.setHeight(width); + rect.translate(0, (height - width) / 2); + } + else if (width > height) + { + rect.setWidth(height); + rect.translate((width - height) / 2, 0); + } + m_icon.paint(&p, rect); } diff --git a/application/widgets/IconLabel.h b/application/widgets/IconLabel.h index a2f1eef3..6d212c4c 100644 --- a/application/widgets/IconLabel.h +++ b/application/widgets/IconLabel.h @@ -9,18 +9,18 @@ class QStyleOption; */ class IconLabel : public QWidget { - Q_OBJECT + Q_OBJECT public: - /// Create a line separator. orientation is the orientation of the line. - explicit IconLabel(QWidget *parent, QIcon icon, QSize size); + /// Create a line separator. orientation is the orientation of the line. + explicit IconLabel(QWidget *parent, QIcon icon, QSize size); - virtual QSize sizeHint() const; - virtual void paintEvent(QPaintEvent *); + virtual QSize sizeHint() const; + virtual void paintEvent(QPaintEvent *); - void setIcon(QIcon icon); + void setIcon(QIcon icon); private: - QSize m_size; - QIcon m_icon; + QSize m_size; + QIcon m_icon; }; diff --git a/application/widgets/JavaSettingsWidget.cpp b/application/widgets/JavaSettingsWidget.cpp index 1e9d5546..a11dd1aa 100644 --- a/application/widgets/JavaSettingsWidget.cpp +++ b/application/widgets/JavaSettingsWidget.cpp @@ -19,410 +19,410 @@ JavaSettingsWidget::JavaSettingsWidget(QWidget* parent) : QWidget(parent) { - m_availableMemory = Sys::getSystemRam() / Sys::megabyte; - - goodIcon = MMC->getThemedIcon("status-good"); - yellowIcon = MMC->getThemedIcon("status-yellow"); - badIcon = MMC->getThemedIcon("status-bad"); - setupUi(); - - connect(m_minMemSpinBox, SIGNAL(valueChanged(int)), this, SLOT(memoryValueChanged(int))); - connect(m_maxMemSpinBox, SIGNAL(valueChanged(int)), this, SLOT(memoryValueChanged(int))); - connect(m_permGenSpinBox, SIGNAL(valueChanged(int)), this, SLOT(memoryValueChanged(int))); - connect(m_versionWidget, &VersionSelectWidget::selectedVersionChanged, this, &JavaSettingsWidget::javaVersionSelected); - connect(m_javaBrowseBtn, &QPushButton::clicked, this, &JavaSettingsWidget::on_javaBrowseBtn_clicked); - connect(m_javaPathTextBox, &QLineEdit::textEdited, this, &JavaSettingsWidget::javaPathEdited); - connect(m_javaStatusBtn, &QToolButton::clicked, this, &JavaSettingsWidget::on_javaStatusBtn_clicked); + m_availableMemory = Sys::getSystemRam() / Sys::megabyte; + + goodIcon = MMC->getThemedIcon("status-good"); + yellowIcon = MMC->getThemedIcon("status-yellow"); + badIcon = MMC->getThemedIcon("status-bad"); + setupUi(); + + connect(m_minMemSpinBox, SIGNAL(valueChanged(int)), this, SLOT(memoryValueChanged(int))); + connect(m_maxMemSpinBox, SIGNAL(valueChanged(int)), this, SLOT(memoryValueChanged(int))); + connect(m_permGenSpinBox, SIGNAL(valueChanged(int)), this, SLOT(memoryValueChanged(int))); + connect(m_versionWidget, &VersionSelectWidget::selectedVersionChanged, this, &JavaSettingsWidget::javaVersionSelected); + connect(m_javaBrowseBtn, &QPushButton::clicked, this, &JavaSettingsWidget::on_javaBrowseBtn_clicked); + connect(m_javaPathTextBox, &QLineEdit::textEdited, this, &JavaSettingsWidget::javaPathEdited); + connect(m_javaStatusBtn, &QToolButton::clicked, this, &JavaSettingsWidget::on_javaStatusBtn_clicked); } void JavaSettingsWidget::setupUi() { - setObjectName(QStringLiteral("javaSettingsWidget")); - m_verticalLayout = new QVBoxLayout(this); - m_verticalLayout->setObjectName(QStringLiteral("verticalLayout")); - - m_versionWidget = new VersionSelectWidget(this); - m_verticalLayout->addWidget(m_versionWidget); - - m_horizontalLayout = new QHBoxLayout(); - m_horizontalLayout->setObjectName(QStringLiteral("horizontalLayout")); - m_javaPathTextBox = new QLineEdit(this); - m_javaPathTextBox->setObjectName(QStringLiteral("javaPathTextBox")); - - m_horizontalLayout->addWidget(m_javaPathTextBox); - - m_javaBrowseBtn = new QPushButton(this); - m_javaBrowseBtn->setObjectName(QStringLiteral("javaBrowseBtn")); - - m_horizontalLayout->addWidget(m_javaBrowseBtn); - - m_javaStatusBtn = new QToolButton(this); - m_javaStatusBtn->setIcon(yellowIcon); - m_horizontalLayout->addWidget(m_javaStatusBtn); - - m_verticalLayout->addLayout(m_horizontalLayout); - - m_memoryGroupBox = new QGroupBox(this); - m_memoryGroupBox->setObjectName(QStringLiteral("memoryGroupBox")); - m_gridLayout_2 = new QGridLayout(m_memoryGroupBox); - m_gridLayout_2->setObjectName(QStringLiteral("gridLayout_2")); - - m_labelMinMem = new QLabel(m_memoryGroupBox); - m_labelMinMem->setObjectName(QStringLiteral("labelMinMem")); - m_gridLayout_2->addWidget(m_labelMinMem, 0, 0, 1, 1); - - m_minMemSpinBox = new QSpinBox(m_memoryGroupBox); - m_minMemSpinBox->setObjectName(QStringLiteral("minMemSpinBox")); - m_minMemSpinBox->setSuffix(QStringLiteral(" MB")); - m_minMemSpinBox->setMinimum(128); - m_minMemSpinBox->setMaximum(m_availableMemory); - m_minMemSpinBox->setSingleStep(128); - m_labelMinMem->setBuddy(m_minMemSpinBox); - m_gridLayout_2->addWidget(m_minMemSpinBox, 0, 1, 1, 1); - - m_labelMaxMem = new QLabel(m_memoryGroupBox); - m_labelMaxMem->setObjectName(QStringLiteral("labelMaxMem")); - m_gridLayout_2->addWidget(m_labelMaxMem, 1, 0, 1, 1); - - m_maxMemSpinBox = new QSpinBox(m_memoryGroupBox); - m_maxMemSpinBox->setObjectName(QStringLiteral("maxMemSpinBox")); - m_maxMemSpinBox->setSuffix(QStringLiteral(" MB")); - m_maxMemSpinBox->setMinimum(128); - m_maxMemSpinBox->setMaximum(m_availableMemory); - m_maxMemSpinBox->setSingleStep(128); - m_labelMaxMem->setBuddy(m_maxMemSpinBox); - m_gridLayout_2->addWidget(m_maxMemSpinBox, 1, 1, 1, 1); - - m_labelPermGen = new QLabel(m_memoryGroupBox); - m_labelPermGen->setObjectName(QStringLiteral("labelPermGen")); - m_labelPermGen->setText(QStringLiteral("PermGen:")); - m_gridLayout_2->addWidget(m_labelPermGen, 2, 0, 1, 1); - m_labelPermGen->setVisible(false); - - m_permGenSpinBox = new QSpinBox(m_memoryGroupBox); - m_permGenSpinBox->setObjectName(QStringLiteral("permGenSpinBox")); - m_permGenSpinBox->setSuffix(QStringLiteral(" MB")); - m_permGenSpinBox->setMinimum(64); - m_permGenSpinBox->setMaximum(m_availableMemory); - m_permGenSpinBox->setSingleStep(8); - m_gridLayout_2->addWidget(m_permGenSpinBox, 2, 1, 1, 1); - m_permGenSpinBox->setVisible(false); - - m_verticalLayout->addWidget(m_memoryGroupBox); - - retranslate(); + setObjectName(QStringLiteral("javaSettingsWidget")); + m_verticalLayout = new QVBoxLayout(this); + m_verticalLayout->setObjectName(QStringLiteral("verticalLayout")); + + m_versionWidget = new VersionSelectWidget(this); + m_verticalLayout->addWidget(m_versionWidget); + + m_horizontalLayout = new QHBoxLayout(); + m_horizontalLayout->setObjectName(QStringLiteral("horizontalLayout")); + m_javaPathTextBox = new QLineEdit(this); + m_javaPathTextBox->setObjectName(QStringLiteral("javaPathTextBox")); + + m_horizontalLayout->addWidget(m_javaPathTextBox); + + m_javaBrowseBtn = new QPushButton(this); + m_javaBrowseBtn->setObjectName(QStringLiteral("javaBrowseBtn")); + + m_horizontalLayout->addWidget(m_javaBrowseBtn); + + m_javaStatusBtn = new QToolButton(this); + m_javaStatusBtn->setIcon(yellowIcon); + m_horizontalLayout->addWidget(m_javaStatusBtn); + + m_verticalLayout->addLayout(m_horizontalLayout); + + m_memoryGroupBox = new QGroupBox(this); + m_memoryGroupBox->setObjectName(QStringLiteral("memoryGroupBox")); + m_gridLayout_2 = new QGridLayout(m_memoryGroupBox); + m_gridLayout_2->setObjectName(QStringLiteral("gridLayout_2")); + + m_labelMinMem = new QLabel(m_memoryGroupBox); + m_labelMinMem->setObjectName(QStringLiteral("labelMinMem")); + m_gridLayout_2->addWidget(m_labelMinMem, 0, 0, 1, 1); + + m_minMemSpinBox = new QSpinBox(m_memoryGroupBox); + m_minMemSpinBox->setObjectName(QStringLiteral("minMemSpinBox")); + m_minMemSpinBox->setSuffix(QStringLiteral(" MB")); + m_minMemSpinBox->setMinimum(128); + m_minMemSpinBox->setMaximum(m_availableMemory); + m_minMemSpinBox->setSingleStep(128); + m_labelMinMem->setBuddy(m_minMemSpinBox); + m_gridLayout_2->addWidget(m_minMemSpinBox, 0, 1, 1, 1); + + m_labelMaxMem = new QLabel(m_memoryGroupBox); + m_labelMaxMem->setObjectName(QStringLiteral("labelMaxMem")); + m_gridLayout_2->addWidget(m_labelMaxMem, 1, 0, 1, 1); + + m_maxMemSpinBox = new QSpinBox(m_memoryGroupBox); + m_maxMemSpinBox->setObjectName(QStringLiteral("maxMemSpinBox")); + m_maxMemSpinBox->setSuffix(QStringLiteral(" MB")); + m_maxMemSpinBox->setMinimum(128); + m_maxMemSpinBox->setMaximum(m_availableMemory); + m_maxMemSpinBox->setSingleStep(128); + m_labelMaxMem->setBuddy(m_maxMemSpinBox); + m_gridLayout_2->addWidget(m_maxMemSpinBox, 1, 1, 1, 1); + + m_labelPermGen = new QLabel(m_memoryGroupBox); + m_labelPermGen->setObjectName(QStringLiteral("labelPermGen")); + m_labelPermGen->setText(QStringLiteral("PermGen:")); + m_gridLayout_2->addWidget(m_labelPermGen, 2, 0, 1, 1); + m_labelPermGen->setVisible(false); + + m_permGenSpinBox = new QSpinBox(m_memoryGroupBox); + m_permGenSpinBox->setObjectName(QStringLiteral("permGenSpinBox")); + m_permGenSpinBox->setSuffix(QStringLiteral(" MB")); + m_permGenSpinBox->setMinimum(64); + m_permGenSpinBox->setMaximum(m_availableMemory); + m_permGenSpinBox->setSingleStep(8); + m_gridLayout_2->addWidget(m_permGenSpinBox, 2, 1, 1, 1); + m_permGenSpinBox->setVisible(false); + + m_verticalLayout->addWidget(m_memoryGroupBox); + + retranslate(); } void JavaSettingsWidget::initialize() { - m_versionWidget->initialize(MMC->javalist().get()); - m_versionWidget->setResizeOn(2); - auto s = MMC->settings(); - // Memory - observedMinMemory = s->get("MinMemAlloc").toInt(); - observedMaxMemory = s->get("MaxMemAlloc").toInt(); - observedPermGenMemory = s->get("PermGen").toInt(); - m_minMemSpinBox->setValue(observedMinMemory); - m_maxMemSpinBox->setValue(observedMaxMemory); - m_permGenSpinBox->setValue(observedPermGenMemory); + m_versionWidget->initialize(MMC->javalist().get()); + m_versionWidget->setResizeOn(2); + auto s = MMC->settings(); + // Memory + observedMinMemory = s->get("MinMemAlloc").toInt(); + observedMaxMemory = s->get("MaxMemAlloc").toInt(); + observedPermGenMemory = s->get("PermGen").toInt(); + m_minMemSpinBox->setValue(observedMinMemory); + m_maxMemSpinBox->setValue(observedMaxMemory); + m_permGenSpinBox->setValue(observedPermGenMemory); } void JavaSettingsWidget::refresh() { - m_versionWidget->loadList(); + m_versionWidget->loadList(); } JavaSettingsWidget::ValidationStatus JavaSettingsWidget::validate() { - switch(javaStatus) - { - default: - case JavaStatus::NotSet: - case JavaStatus::DoesNotExist: - case JavaStatus::DoesNotStart: - case JavaStatus::ReturnedInvalidData: - { - int button = CustomMessageBox::selectable( - this, - tr("No Java version selected"), - tr("You didn't select a Java version or selected something that doesn't work.\n" - "MultiMC will not be able to start Minecraft.\n" - "Do you wish to proceed without any Java?" - "\n\n" - "You can change the Java version in the settings later.\n" - ), - QMessageBox::Warning, - QMessageBox::Yes | QMessageBox::No, - QMessageBox::NoButton - )->exec(); - if(button == QMessageBox::No) - { - return ValidationStatus::Bad; - } - return ValidationStatus::JavaBad; - } - break; - case JavaStatus::Pending: - { - return ValidationStatus::Bad; - } - case JavaStatus::Good: - { - return ValidationStatus::AllOK; - } - } + switch(javaStatus) + { + default: + case JavaStatus::NotSet: + case JavaStatus::DoesNotExist: + case JavaStatus::DoesNotStart: + case JavaStatus::ReturnedInvalidData: + { + int button = CustomMessageBox::selectable( + this, + tr("No Java version selected"), + tr("You didn't select a Java version or selected something that doesn't work.\n" + "MultiMC will not be able to start Minecraft.\n" + "Do you wish to proceed without any Java?" + "\n\n" + "You can change the Java version in the settings later.\n" + ), + QMessageBox::Warning, + QMessageBox::Yes | QMessageBox::No, + QMessageBox::NoButton + )->exec(); + if(button == QMessageBox::No) + { + return ValidationStatus::Bad; + } + return ValidationStatus::JavaBad; + } + break; + case JavaStatus::Pending: + { + return ValidationStatus::Bad; + } + case JavaStatus::Good: + { + return ValidationStatus::AllOK; + } + } } QString JavaSettingsWidget::javaPath() const { - return m_javaPathTextBox->text(); + return m_javaPathTextBox->text(); } int JavaSettingsWidget::maxHeapSize() const { - return m_maxMemSpinBox->value(); + return m_maxMemSpinBox->value(); } int JavaSettingsWidget::minHeapSize() const { - return m_minMemSpinBox->value(); + return m_minMemSpinBox->value(); } bool JavaSettingsWidget::permGenEnabled() const { - return m_permGenSpinBox->isVisible(); + return m_permGenSpinBox->isVisible(); } int JavaSettingsWidget::permGenSize() const { - return m_permGenSpinBox->value(); + return m_permGenSpinBox->value(); } void JavaSettingsWidget::memoryValueChanged(int) { - bool actuallyChanged = false; - int min = m_minMemSpinBox->value(); - int max = m_maxMemSpinBox->value(); - int permgen = m_permGenSpinBox->value(); - QObject *obj = sender(); - if (obj == m_minMemSpinBox && min != observedMinMemory) - { - observedMinMemory = min; - actuallyChanged = true; - if (min > max) - { - observedMaxMemory = min; - m_maxMemSpinBox->setValue(min); - } - } - else if (obj == m_maxMemSpinBox && max != observedMaxMemory) - { - observedMaxMemory = max; - actuallyChanged = true; - if (min > max) - { - observedMinMemory = max; - m_minMemSpinBox->setValue(max); - } - } - else if (obj == m_permGenSpinBox && permgen != observedPermGenMemory) - { - observedPermGenMemory = permgen; - actuallyChanged = true; - } - if(actuallyChanged) - { - checkJavaPathOnEdit(m_javaPathTextBox->text()); - } + bool actuallyChanged = false; + int min = m_minMemSpinBox->value(); + int max = m_maxMemSpinBox->value(); + int permgen = m_permGenSpinBox->value(); + QObject *obj = sender(); + if (obj == m_minMemSpinBox && min != observedMinMemory) + { + observedMinMemory = min; + actuallyChanged = true; + if (min > max) + { + observedMaxMemory = min; + m_maxMemSpinBox->setValue(min); + } + } + else if (obj == m_maxMemSpinBox && max != observedMaxMemory) + { + observedMaxMemory = max; + actuallyChanged = true; + if (min > max) + { + observedMinMemory = max; + m_minMemSpinBox->setValue(max); + } + } + else if (obj == m_permGenSpinBox && permgen != observedPermGenMemory) + { + observedPermGenMemory = permgen; + actuallyChanged = true; + } + if(actuallyChanged) + { + checkJavaPathOnEdit(m_javaPathTextBox->text()); + } } void JavaSettingsWidget::javaVersionSelected(BaseVersionPtr version) { - auto java = std::dynamic_pointer_cast(version); - if(!java) - { - return; - } - auto visible = java->id.requiresPermGen(); - m_labelPermGen->setVisible(visible); - m_permGenSpinBox->setVisible(visible); - m_javaPathTextBox->setText(java->path); - checkJavaPath(java->path); + auto java = std::dynamic_pointer_cast(version); + if(!java) + { + return; + } + auto visible = java->id.requiresPermGen(); + m_labelPermGen->setVisible(visible); + m_permGenSpinBox->setVisible(visible); + m_javaPathTextBox->setText(java->path); + checkJavaPath(java->path); } void JavaSettingsWidget::on_javaBrowseBtn_clicked() { - QString filter; + QString filter; #if defined Q_OS_WIN32 - filter = "Java (javaw.exe)"; + filter = "Java (javaw.exe)"; #else - filter = "Java (java)"; + filter = "Java (java)"; #endif - QString raw_path = QFileDialog::getOpenFileName(this, tr("Find Java executable"), QString(), filter); - if(raw_path.isEmpty()) - { - return; - } - QString cooked_path = FS::NormalizePath(raw_path); - m_javaPathTextBox->setText(cooked_path); - checkJavaPath(cooked_path); + QString raw_path = QFileDialog::getOpenFileName(this, tr("Find Java executable"), QString(), filter); + if(raw_path.isEmpty()) + { + return; + } + QString cooked_path = FS::NormalizePath(raw_path); + m_javaPathTextBox->setText(cooked_path); + checkJavaPath(cooked_path); } void JavaSettingsWidget::on_javaStatusBtn_clicked() { - QString text; - bool failed = false; - switch(javaStatus) - { - case JavaStatus::NotSet: - checkJavaPath(m_javaPathTextBox->text()); - return; - case JavaStatus::DoesNotExist: - text += QObject::tr("The specified file either doesn't exist or is not a proper executable."); - failed = true; - break; - case JavaStatus::DoesNotStart: - { - text += QObject::tr("The specified java binary didn't start properly.
"); - auto htmlError = m_result.errorLog; - if(!htmlError.isEmpty()) - { - htmlError.replace('\n', "
"); - text += QString("%1").arg(htmlError); - } - failed = true; - break; - } - case JavaStatus::ReturnedInvalidData: - { - text += QObject::tr("The specified java binary returned unexpected results:
"); - auto htmlOut = m_result.outLog; - if(!htmlOut.isEmpty()) - { - htmlOut.replace('\n', "
"); - text += QString("%1").arg(htmlOut); - } - failed = true; - break; - } - case JavaStatus::Good: - text += QObject::tr("Java test succeeded!
Platform reported: %1
Java version " - "reported: %2
").arg(m_result.realPlatform, m_result.javaVersion.toString()); - break; - case JavaStatus::Pending: - // TODO: abort here? - return; - } - CustomMessageBox::selectable( - this, - failed ? QObject::tr("Java test success") : QObject::tr("Java test failure"), - text, - failed ? QMessageBox::Critical : QMessageBox::Information - )->show(); + QString text; + bool failed = false; + switch(javaStatus) + { + case JavaStatus::NotSet: + checkJavaPath(m_javaPathTextBox->text()); + return; + case JavaStatus::DoesNotExist: + text += QObject::tr("The specified file either doesn't exist or is not a proper executable."); + failed = true; + break; + case JavaStatus::DoesNotStart: + { + text += QObject::tr("The specified java binary didn't start properly.
"); + auto htmlError = m_result.errorLog; + if(!htmlError.isEmpty()) + { + htmlError.replace('\n', "
"); + text += QString("%1").arg(htmlError); + } + failed = true; + break; + } + case JavaStatus::ReturnedInvalidData: + { + text += QObject::tr("The specified java binary returned unexpected results:
"); + auto htmlOut = m_result.outLog; + if(!htmlOut.isEmpty()) + { + htmlOut.replace('\n', "
"); + text += QString("%1").arg(htmlOut); + } + failed = true; + break; + } + case JavaStatus::Good: + text += QObject::tr("Java test succeeded!
Platform reported: %1
Java version " + "reported: %2
").arg(m_result.realPlatform, m_result.javaVersion.toString()); + break; + case JavaStatus::Pending: + // TODO: abort here? + return; + } + CustomMessageBox::selectable( + this, + failed ? QObject::tr("Java test success") : QObject::tr("Java test failure"), + text, + failed ? QMessageBox::Critical : QMessageBox::Information + )->show(); } void JavaSettingsWidget::setJavaStatus(JavaSettingsWidget::JavaStatus status) { - javaStatus = status; - switch(javaStatus) - { - case JavaStatus::Good: - m_javaStatusBtn->setIcon(goodIcon); - break; - case JavaStatus::NotSet: - case JavaStatus::Pending: - m_javaStatusBtn->setIcon(yellowIcon); - break; - default: - m_javaStatusBtn->setIcon(badIcon); - break; - } + javaStatus = status; + switch(javaStatus) + { + case JavaStatus::Good: + m_javaStatusBtn->setIcon(goodIcon); + break; + case JavaStatus::NotSet: + case JavaStatus::Pending: + m_javaStatusBtn->setIcon(yellowIcon); + break; + default: + m_javaStatusBtn->setIcon(badIcon); + break; + } } void JavaSettingsWidget::javaPathEdited(const QString& path) { - checkJavaPathOnEdit(path); + checkJavaPathOnEdit(path); } void JavaSettingsWidget::checkJavaPathOnEdit(const QString& path) { - auto realPath = FS::ResolveExecutable(path); - QFileInfo pathInfo(realPath); - if (pathInfo.baseName().toLower().contains("java")) - { - checkJavaPath(path); - } - else - { - if(!m_checker) - { - setJavaStatus(JavaStatus::NotSet); - } - } + auto realPath = FS::ResolveExecutable(path); + QFileInfo pathInfo(realPath); + if (pathInfo.baseName().toLower().contains("java")) + { + checkJavaPath(path); + } + else + { + if(!m_checker) + { + setJavaStatus(JavaStatus::NotSet); + } + } } void JavaSettingsWidget::checkJavaPath(const QString &path) { - if(m_checker) - { - queuedCheck = path; - return; - } - auto realPath = FS::ResolveExecutable(path); - if(realPath.isNull()) - { - setJavaStatus(JavaStatus::DoesNotExist); - return; - } - setJavaStatus(JavaStatus::Pending); - m_checker.reset(new JavaChecker()); - m_checker->m_path = path; - m_checker->m_minMem = m_minMemSpinBox->value(); - m_checker->m_maxMem = m_maxMemSpinBox->value(); - if(m_permGenSpinBox->isVisible()) - { - m_checker->m_permGen = m_permGenSpinBox->value(); - } - connect(m_checker.get(), &JavaChecker::checkFinished, this, &JavaSettingsWidget::checkFinished); - m_checker->performCheck(); + if(m_checker) + { + queuedCheck = path; + return; + } + auto realPath = FS::ResolveExecutable(path); + if(realPath.isNull()) + { + setJavaStatus(JavaStatus::DoesNotExist); + return; + } + setJavaStatus(JavaStatus::Pending); + m_checker.reset(new JavaChecker()); + m_checker->m_path = path; + m_checker->m_minMem = m_minMemSpinBox->value(); + m_checker->m_maxMem = m_maxMemSpinBox->value(); + if(m_permGenSpinBox->isVisible()) + { + m_checker->m_permGen = m_permGenSpinBox->value(); + } + connect(m_checker.get(), &JavaChecker::checkFinished, this, &JavaSettingsWidget::checkFinished); + m_checker->performCheck(); } void JavaSettingsWidget::checkFinished(JavaCheckResult result) { - m_result = result; - switch(result.validity) - { - case JavaCheckResult::Validity::Valid: - { - setJavaStatus(JavaStatus::Good); - break; - } - case JavaCheckResult::Validity::ReturnedInvalidData: - { - setJavaStatus(JavaStatus::ReturnedInvalidData); - break; - } - case JavaCheckResult::Validity::Errored: - { - setJavaStatus(JavaStatus::DoesNotStart); - break; - } - } - m_checker.reset(); - if(!queuedCheck.isNull()) - { - checkJavaPath(queuedCheck); - queuedCheck.clear(); - } + m_result = result; + switch(result.validity) + { + case JavaCheckResult::Validity::Valid: + { + setJavaStatus(JavaStatus::Good); + break; + } + case JavaCheckResult::Validity::ReturnedInvalidData: + { + setJavaStatus(JavaStatus::ReturnedInvalidData); + break; + } + case JavaCheckResult::Validity::Errored: + { + setJavaStatus(JavaStatus::DoesNotStart); + break; + } + } + m_checker.reset(); + if(!queuedCheck.isNull()) + { + checkJavaPath(queuedCheck); + queuedCheck.clear(); + } } void JavaSettingsWidget::retranslate() { - m_memoryGroupBox->setTitle(tr("Memory")); - m_maxMemSpinBox->setToolTip(tr("The maximum amount of memory Minecraft is allowed to use.")); - m_labelMinMem->setText(tr("Minimum memory allocation:")); - m_labelMaxMem->setText(tr("Maximum memory allocation:")); - m_minMemSpinBox->setToolTip(tr("The amount of memory Minecraft is started with.")); - m_permGenSpinBox->setToolTip(tr("The amount of memory available to store loaded Java classes.")); - m_javaBrowseBtn->setText(tr("Browse")); + m_memoryGroupBox->setTitle(tr("Memory")); + m_maxMemSpinBox->setToolTip(tr("The maximum amount of memory Minecraft is allowed to use.")); + m_labelMinMem->setText(tr("Minimum memory allocation:")); + m_labelMaxMem->setText(tr("Maximum memory allocation:")); + m_minMemSpinBox->setToolTip(tr("The amount of memory Minecraft is started with.")); + m_permGenSpinBox->setToolTip(tr("The amount of memory available to store loaded Java classes.")); + m_javaBrowseBtn->setText(tr("Browse")); } diff --git a/application/widgets/JavaSettingsWidget.h b/application/widgets/JavaSettingsWidget.h index 3a94f851..0d280daf 100644 --- a/application/widgets/JavaSettingsWidget.h +++ b/application/widgets/JavaSettingsWidget.h @@ -22,81 +22,81 @@ class QToolButton; */ class JavaSettingsWidget : public QWidget { - Q_OBJECT + Q_OBJECT public: - explicit JavaSettingsWidget(QWidget *parent); - virtual ~JavaSettingsWidget() {}; + explicit JavaSettingsWidget(QWidget *parent); + virtual ~JavaSettingsWidget() {}; - enum class JavaStatus - { - NotSet, - Pending, - Good, - DoesNotExist, - DoesNotStart, - ReturnedInvalidData - } javaStatus = JavaStatus::NotSet; + enum class JavaStatus + { + NotSet, + Pending, + Good, + DoesNotExist, + DoesNotStart, + ReturnedInvalidData + } javaStatus = JavaStatus::NotSet; - enum class ValidationStatus - { - Bad, - JavaBad, - AllOK - }; + enum class ValidationStatus + { + Bad, + JavaBad, + AllOK + }; - void refresh(); - void initialize(); - ValidationStatus validate(); - void retranslate(); + void refresh(); + void initialize(); + ValidationStatus validate(); + void retranslate(); - bool permGenEnabled() const; - int permGenSize() const; - int minHeapSize() const; - int maxHeapSize() const; - QString javaPath() const; + bool permGenEnabled() const; + int permGenSize() const; + int minHeapSize() const; + int maxHeapSize() const; + QString javaPath() const; protected slots: - void memoryValueChanged(int); - void javaPathEdited(const QString &path); - void javaVersionSelected(BaseVersionPtr version); - void on_javaBrowseBtn_clicked(); - void on_javaStatusBtn_clicked(); - void checkFinished(JavaCheckResult result); + void memoryValueChanged(int); + void javaPathEdited(const QString &path); + void javaVersionSelected(BaseVersionPtr version); + void on_javaBrowseBtn_clicked(); + void on_javaStatusBtn_clicked(); + void checkFinished(JavaCheckResult result); protected: /* methods */ - void checkJavaPathOnEdit(const QString &path); - void checkJavaPath(const QString &path); - void setJavaStatus(JavaStatus status); - void setupUi(); + void checkJavaPathOnEdit(const QString &path); + void checkJavaPath(const QString &path); + void setJavaStatus(JavaStatus status); + void setupUi(); private: /* data */ - VersionSelectWidget *m_versionWidget = nullptr; - QVBoxLayout *m_verticalLayout = nullptr; + VersionSelectWidget *m_versionWidget = nullptr; + QVBoxLayout *m_verticalLayout = nullptr; - QLineEdit * m_javaPathTextBox = nullptr; - QPushButton * m_javaBrowseBtn = nullptr; - QToolButton * m_javaStatusBtn = nullptr; - QHBoxLayout *m_horizontalLayout = nullptr; + QLineEdit * m_javaPathTextBox = nullptr; + QPushButton * m_javaBrowseBtn = nullptr; + QToolButton * m_javaStatusBtn = nullptr; + QHBoxLayout *m_horizontalLayout = nullptr; - QGroupBox *m_memoryGroupBox = nullptr; - QGridLayout *m_gridLayout_2 = nullptr; - QSpinBox *m_maxMemSpinBox = nullptr; - QLabel *m_labelMinMem = nullptr; - QLabel *m_labelMaxMem = nullptr; - QSpinBox *m_minMemSpinBox = nullptr; - QLabel *m_labelPermGen = nullptr; - QSpinBox *m_permGenSpinBox = nullptr; - QIcon goodIcon; - QIcon yellowIcon; - QIcon badIcon; + QGroupBox *m_memoryGroupBox = nullptr; + QGridLayout *m_gridLayout_2 = nullptr; + QSpinBox *m_maxMemSpinBox = nullptr; + QLabel *m_labelMinMem = nullptr; + QLabel *m_labelMaxMem = nullptr; + QSpinBox *m_minMemSpinBox = nullptr; + QLabel *m_labelPermGen = nullptr; + QSpinBox *m_permGenSpinBox = nullptr; + QIcon goodIcon; + QIcon yellowIcon; + QIcon badIcon; - int observedMinMemory = 0; - int observedMaxMemory = 0; - int observedPermGenMemory = 0; - QString queuedCheck; - uint64_t m_availableMemory = 0ull; - shared_qobject_ptr m_checker; - JavaCheckResult m_result; + int observedMinMemory = 0; + int observedMaxMemory = 0; + int observedPermGenMemory = 0; + QString queuedCheck; + uint64_t m_availableMemory = 0ull; + shared_qobject_ptr m_checker; + JavaCheckResult m_result; }; diff --git a/application/widgets/LabeledToolButton.cpp b/application/widgets/LabeledToolButton.cpp index 744d2e00..ab273b65 100644 --- a/application/widgets/LabeledToolButton.cpp +++ b/application/widgets/LabeledToolButton.cpp @@ -1,4 +1,4 @@ -/* Copyright 2013-2018 MultiMC Contributors +/* Copyright 2013-2019 MultiMC Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,32 +28,32 @@ */ LabeledToolButton::LabeledToolButton(QWidget * parent) - : QToolButton(parent) - , m_label(new QLabel(this)) + : QToolButton(parent) + , m_label(new QLabel(this)) { - //QToolButton::setText(" "); - m_label->setWordWrap(true); - m_label->setMouseTracking(false); - m_label->setAlignment(Qt::AlignCenter); - m_label->setTextInteractionFlags(Qt::NoTextInteraction); - // somehow, this makes word wrap work in the QLabel. yay. - //m_label->setMinimumWidth(100); + //QToolButton::setText(" "); + m_label->setWordWrap(true); + m_label->setMouseTracking(false); + m_label->setAlignment(Qt::AlignCenter); + m_label->setTextInteractionFlags(Qt::NoTextInteraction); + // somehow, this makes word wrap work in the QLabel. yay. + //m_label->setMinimumWidth(100); } QString LabeledToolButton::text() const { - return m_label->text(); + return m_label->text(); } void LabeledToolButton::setText(const QString & text) { - m_label->setText(text); + m_label->setText(text); } void LabeledToolButton::setIcon(QIcon icon) { - m_icon = icon; - resetIcon(); + m_icon = icon; + resetIcon(); } @@ -62,54 +62,54 @@ void LabeledToolButton::setIcon(QIcon icon) */ QSize LabeledToolButton::sizeHint() const { - /* - Q_D(const QToolButton); - if (d->sizeHint.isValid()) - return d->sizeHint; - */ - ensurePolished(); + /* + Q_D(const QToolButton); + if (d->sizeHint.isValid()) + return d->sizeHint; + */ + ensurePolished(); - int w = 0, h = 0; - QStyleOptionToolButton opt; - initStyleOption(&opt); - QSize sz =m_label->sizeHint(); - w = sz.width(); - h = sz.height(); + int w = 0, h = 0; + QStyleOptionToolButton opt; + initStyleOption(&opt); + QSize sz =m_label->sizeHint(); + w = sz.width(); + h = sz.height(); - opt.rect.setSize(QSize(w, h)); // PM_MenuButtonIndicator depends on the height - if (popupMode() == MenuButtonPopup) - w += style()->pixelMetric(QStyle::PM_MenuButtonIndicator, &opt, this); - - QSize rawSize = style()->sizeFromContents(QStyle::CT_ToolButton, &opt, QSize(w, h), this); - QSize sizeHint = rawSize.expandedTo(QApplication::globalStrut()); - return sizeHint; + opt.rect.setSize(QSize(w, h)); // PM_MenuButtonIndicator depends on the height + if (popupMode() == MenuButtonPopup) + w += style()->pixelMetric(QStyle::PM_MenuButtonIndicator, &opt, this); + + QSize rawSize = style()->sizeFromContents(QStyle::CT_ToolButton, &opt, QSize(w, h), this); + QSize sizeHint = rawSize.expandedTo(QApplication::globalStrut()); + return sizeHint; } void LabeledToolButton::resizeEvent(QResizeEvent * event) { - m_label->setGeometry(QRect(4, 4, width()-8, height()-8)); - if(!m_icon.isNull()) - { - resetIcon(); - } - QWidget::resizeEvent(event); + m_label->setGeometry(QRect(4, 4, width()-8, height()-8)); + if(!m_icon.isNull()) + { + resetIcon(); + } + QWidget::resizeEvent(event); } void LabeledToolButton::resetIcon() { - auto iconSz = m_icon.actualSize(QSize(160, 80)); - float w = iconSz.width(); - float h = iconSz.height(); - float ar = w/h; - // FIXME: hardcoded max size of 160x80 - int newW = 80 * ar; - if(newW > 160) - newW = 160; - QSize newSz (newW, 80); - auto pixmap = m_icon.pixmap(newSz); - m_label->setPixmap(pixmap); - m_label->setMinimumHeight(80); - m_label->setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Preferred ); + auto iconSz = m_icon.actualSize(QSize(160, 80)); + float w = iconSz.width(); + float h = iconSz.height(); + float ar = w/h; + // FIXME: hardcoded max size of 160x80 + int newW = 80 * ar; + if(newW > 160) + newW = 160; + QSize newSz (newW, 80); + auto pixmap = m_icon.pixmap(newSz); + m_label->setPixmap(pixmap); + m_label->setMinimumHeight(80); + m_label->setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Preferred ); } diff --git a/application/widgets/LabeledToolButton.h b/application/widgets/LabeledToolButton.h index 151a5c2c..136ebd23 100644 --- a/application/widgets/LabeledToolButton.h +++ b/application/widgets/LabeledToolButton.h @@ -1,4 +1,4 @@ -/* Copyright 2013-2018 MultiMC Contributors +/* Copyright 2013-2019 MultiMC Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,19 +22,19 @@ class QLabel; class LabeledToolButton : public QToolButton { - Q_OBJECT + Q_OBJECT - QLabel * m_label; - QIcon m_icon; + QLabel * m_label; + QIcon m_icon; public: - LabeledToolButton(QWidget * parent = 0); + LabeledToolButton(QWidget * parent = 0); - QString text() const; - void setText(const QString & text); - void setIcon(QIcon icon); - virtual QSize sizeHint() const; + QString text() const; + void setText(const QString & text); + void setIcon(QIcon icon); + virtual QSize sizeHint() const; protected: - void resizeEvent(QResizeEvent * event); - void resetIcon(); + void resizeEvent(QResizeEvent * event); + void resetIcon(); }; diff --git a/application/widgets/LanguageSelectionWidget.cpp b/application/widgets/LanguageSelectionWidget.cpp new file mode 100644 index 00000000..80e26b39 --- /dev/null +++ b/application/widgets/LanguageSelectionWidget.cpp @@ -0,0 +1,68 @@ +#include "LanguageSelectionWidget.h" + +#include +#include +#include +#include +#include "MultiMC.h" +#include "translations/TranslationsModel.h" + +LanguageSelectionWidget::LanguageSelectionWidget(QWidget *parent) : + QWidget(parent) +{ + verticalLayout = new QVBoxLayout(this); + verticalLayout->setObjectName(QStringLiteral("verticalLayout")); + languageView = new QTreeView(this); + languageView->setObjectName(QStringLiteral("languageView")); + languageView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + languageView->setAlternatingRowColors(true); + languageView->setRootIsDecorated(false); + languageView->setItemsExpandable(false); + languageView->setWordWrap(true); + languageView->header()->setCascadingSectionResizes(true); + languageView->header()->setStretchLastSection(false); + verticalLayout->addWidget(languageView); + helpUsLabel = new QLabel(this); + helpUsLabel->setObjectName(QStringLiteral("helpUsLabel")); + helpUsLabel->setTextInteractionFlags(Qt::LinksAccessibleByMouse); + helpUsLabel->setOpenExternalLinks(true); + helpUsLabel->setWordWrap(true); + verticalLayout->addWidget(helpUsLabel); + + auto translations = MMC->translations(); + auto index = translations->selectedIndex(); + languageView->setModel(translations.get()); + languageView->setCurrentIndex(index); + languageView->header()->setSectionResizeMode(QHeaderView::ResizeToContents); + languageView->header()->setSectionResizeMode(0, QHeaderView::Stretch); + connect(languageView->selectionModel(), &QItemSelectionModel::currentRowChanged, this, &LanguageSelectionWidget::languageRowChanged); + verticalLayout->setContentsMargins(0,0,0,0); +} + +QString LanguageSelectionWidget::getSelectedLanguageKey() const +{ + auto translations = MMC->translations(); + return translations->data(languageView->currentIndex(), Qt::UserRole).toString(); +} + +void LanguageSelectionWidget::retranslate() +{ + QString text = + tr("Don't see your language or the quality is poor?") + + "
" + + QString("%1").arg(tr("Help us with translations!")); + helpUsLabel->setText(text); + +} + +void LanguageSelectionWidget::languageRowChanged(const QModelIndex& current, const QModelIndex& previous) +{ + if (current == previous) + { + return; + } + auto translations = MMC->translations(); + QString key = translations->data(current, Qt::UserRole).toString(); + translations->selectLanguage(key); + translations->updateLanguage(key); +} diff --git a/application/widgets/LanguageSelectionWidget.h b/application/widgets/LanguageSelectionWidget.h new file mode 100644 index 00000000..03e29bd8 --- /dev/null +++ b/application/widgets/LanguageSelectionWidget.h @@ -0,0 +1,41 @@ +/* Copyright 2013-2019 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +class QVBoxLayout; +class QTreeView; +class QLabel; + +class LanguageSelectionWidget: public QWidget +{ + Q_OBJECT +public: + explicit LanguageSelectionWidget(QWidget *parent = 0); + virtual ~LanguageSelectionWidget() { }; + + QString getSelectedLanguageKey() const; + void retranslate(); + +protected slots: + void languageRowChanged(const QModelIndex ¤t, const QModelIndex &previous); + +private: + QVBoxLayout *verticalLayout = nullptr; + QTreeView *languageView = nullptr; + QLabel *helpUsLabel = nullptr; +}; diff --git a/application/widgets/LineSeparator.cpp b/application/widgets/LineSeparator.cpp index f4ee173d..d03e6762 100644 --- a/application/widgets/LineSeparator.cpp +++ b/application/widgets/LineSeparator.cpp @@ -7,31 +7,31 @@ void LineSeparator::initStyleOption(QStyleOption *option) const { - option->initFrom(this); - // in a horizontal layout, the line is vertical (and vice versa) - if (m_orientation == Qt::Vertical) - option->state |= QStyle::State_Horizontal; + option->initFrom(this); + // in a horizontal layout, the line is vertical (and vice versa) + if (m_orientation == Qt::Vertical) + option->state |= QStyle::State_Horizontal; } LineSeparator::LineSeparator(QWidget *parent, Qt::Orientation orientation) - : QWidget(parent), m_orientation(orientation) + : QWidget(parent), m_orientation(orientation) { - setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); + setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); } QSize LineSeparator::sizeHint() const { - QStyleOption opt; - initStyleOption(&opt); - const int extent = - style()->pixelMetric(QStyle::PM_ToolBarSeparatorExtent, &opt, parentWidget()); - return QSize(extent, extent); + QStyleOption opt; + initStyleOption(&opt); + const int extent = + style()->pixelMetric(QStyle::PM_ToolBarSeparatorExtent, &opt, parentWidget()); + return QSize(extent, extent); } void LineSeparator::paintEvent(QPaintEvent *) { - QPainter p(this); - QStyleOption opt; - initStyleOption(&opt); - style()->drawPrimitive(QStyle::PE_IndicatorToolBarSeparator, &opt, &p, parentWidget()); + QPainter p(this); + QStyleOption opt; + initStyleOption(&opt); + style()->drawPrimitive(QStyle::PE_IndicatorToolBarSeparator, &opt, &p, parentWidget()); } diff --git a/application/widgets/LineSeparator.h b/application/widgets/LineSeparator.h index 9546e747..22927b68 100644 --- a/application/widgets/LineSeparator.h +++ b/application/widgets/LineSeparator.h @@ -5,14 +5,14 @@ class QStyleOption; class LineSeparator : public QWidget { - Q_OBJECT + Q_OBJECT public: - /// Create a line separator. orientation is the orientation of the line. - explicit LineSeparator(QWidget *parent, Qt::Orientation orientation = Qt::Horizontal); - QSize sizeHint() const; - void paintEvent(QPaintEvent *); - void initStyleOption(QStyleOption *option) const; + /// Create a line separator. orientation is the orientation of the line. + explicit LineSeparator(QWidget *parent, Qt::Orientation orientation = Qt::Horizontal); + QSize sizeHint() const; + void paintEvent(QPaintEvent *); + void initStyleOption(QStyleOption *option) const; private: - Qt::Orientation m_orientation = Qt::Horizontal; + Qt::Orientation m_orientation = Qt::Horizontal; }; diff --git a/application/widgets/LogView.cpp b/application/widgets/LogView.cpp index 8e0346fa..26a2a527 100644 --- a/application/widgets/LogView.cpp +++ b/application/widgets/LogView.cpp @@ -4,141 +4,141 @@ LogView::LogView(QWidget* parent) : QPlainTextEdit(parent) { - setWordWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere); - m_defaultFormat = new QTextCharFormat(currentCharFormat()); + setWordWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere); + m_defaultFormat = new QTextCharFormat(currentCharFormat()); } LogView::~LogView() { - delete m_defaultFormat; + delete m_defaultFormat; } void LogView::setWordWrap(bool wrapping) { - if(wrapping) - { - setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - setLineWrapMode(QPlainTextEdit::WidgetWidth); - } - else - { - setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); - setLineWrapMode(QPlainTextEdit::NoWrap); - } + if(wrapping) + { + setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + setLineWrapMode(QPlainTextEdit::WidgetWidth); + } + else + { + setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); + setLineWrapMode(QPlainTextEdit::NoWrap); + } } void LogView::setModel(QAbstractItemModel* model) { - if(m_model) - { - disconnect(m_model, &QAbstractItemModel::modelReset, this, &LogView::repopulate); - disconnect(m_model, &QAbstractItemModel::rowsInserted, this, &LogView::rowsInserted); - disconnect(m_model, &QAbstractItemModel::rowsAboutToBeInserted, this, &LogView::rowsAboutToBeInserted); - disconnect(m_model, &QAbstractItemModel::rowsRemoved, this, &LogView::rowsRemoved); - } - m_model = model; - if(m_model) - { - connect(m_model, &QAbstractItemModel::modelReset, this, &LogView::repopulate); - connect(m_model, &QAbstractItemModel::rowsInserted, this, &LogView::rowsInserted); - connect(m_model, &QAbstractItemModel::rowsAboutToBeInserted, this, &LogView::rowsAboutToBeInserted); - connect(m_model, &QAbstractItemModel::rowsRemoved, this, &LogView::rowsRemoved); - connect(m_model, &QAbstractItemModel::destroyed, this, &LogView::modelDestroyed); - } - repopulate(); + if(m_model) + { + disconnect(m_model, &QAbstractItemModel::modelReset, this, &LogView::repopulate); + disconnect(m_model, &QAbstractItemModel::rowsInserted, this, &LogView::rowsInserted); + disconnect(m_model, &QAbstractItemModel::rowsAboutToBeInserted, this, &LogView::rowsAboutToBeInserted); + disconnect(m_model, &QAbstractItemModel::rowsRemoved, this, &LogView::rowsRemoved); + } + m_model = model; + if(m_model) + { + connect(m_model, &QAbstractItemModel::modelReset, this, &LogView::repopulate); + connect(m_model, &QAbstractItemModel::rowsInserted, this, &LogView::rowsInserted); + connect(m_model, &QAbstractItemModel::rowsAboutToBeInserted, this, &LogView::rowsAboutToBeInserted); + connect(m_model, &QAbstractItemModel::rowsRemoved, this, &LogView::rowsRemoved); + connect(m_model, &QAbstractItemModel::destroyed, this, &LogView::modelDestroyed); + } + repopulate(); } QAbstractItemModel * LogView::model() const { - return m_model; + return m_model; } void LogView::modelDestroyed(QObject* model) { - if(m_model == model) - { - setModel(nullptr); - } + if(m_model == model) + { + setModel(nullptr); + } } void LogView::repopulate() { - auto doc = document(); - doc->clear(); - if(!m_model) - { - return; - } - rowsInserted(QModelIndex(), 0, m_model->rowCount() - 1); + auto doc = document(); + doc->clear(); + if(!m_model) + { + return; + } + rowsInserted(QModelIndex(), 0, m_model->rowCount() - 1); } void LogView::rowsAboutToBeInserted(const QModelIndex& parent, int first, int last) { - Q_UNUSED(parent) - Q_UNUSED(first) - Q_UNUSED(last) - QScrollBar *bar = verticalScrollBar(); - int max_bar = bar->maximum(); - int val_bar = bar->value(); - if (m_scroll) - { - m_scroll = (max_bar - val_bar) <= 1; - } - else - { - m_scroll = val_bar == max_bar; - } + Q_UNUSED(parent) + Q_UNUSED(first) + Q_UNUSED(last) + QScrollBar *bar = verticalScrollBar(); + int max_bar = bar->maximum(); + int val_bar = bar->value(); + if (m_scroll) + { + m_scroll = (max_bar - val_bar) <= 1; + } + else + { + m_scroll = val_bar == max_bar; + } } void LogView::rowsInserted(const QModelIndex& parent, int first, int last) { - for(int i = first; i <= last; i++) - { - auto idx = m_model->index(i, 0, parent); - auto text = m_model->data(idx, Qt::DisplayRole).toString(); - QTextCharFormat format(*m_defaultFormat); - auto font = m_model->data(idx, Qt::FontRole); - if(font.isValid()) - { - format.setFont(font.value()); - } - auto fg = m_model->data(idx, Qt::TextColorRole); - if(fg.isValid()) - { - format.setForeground(fg.value()); - } - auto bg = m_model->data(idx, Qt::BackgroundRole); - if(bg.isValid()) - { - format.setBackground(bg.value()); - } - auto workCursor = textCursor(); - workCursor.movePosition(QTextCursor::End); - workCursor.insertText(text, format); - workCursor.insertBlock(); - } - if(m_scroll && !m_scrolling) - { - m_scrolling = true; - QMetaObject::invokeMethod( this, "scrollToBottom", Qt::QueuedConnection); - } + for(int i = first; i <= last; i++) + { + auto idx = m_model->index(i, 0, parent); + auto text = m_model->data(idx, Qt::DisplayRole).toString(); + QTextCharFormat format(*m_defaultFormat); + auto font = m_model->data(idx, Qt::FontRole); + if(font.isValid()) + { + format.setFont(font.value()); + } + auto fg = m_model->data(idx, Qt::TextColorRole); + if(fg.isValid()) + { + format.setForeground(fg.value()); + } + auto bg = m_model->data(idx, Qt::BackgroundRole); + if(bg.isValid()) + { + format.setBackground(bg.value()); + } + auto workCursor = textCursor(); + workCursor.movePosition(QTextCursor::End); + workCursor.insertText(text, format); + workCursor.insertBlock(); + } + if(m_scroll && !m_scrolling) + { + m_scrolling = true; + QMetaObject::invokeMethod( this, "scrollToBottom", Qt::QueuedConnection); + } } void LogView::rowsRemoved(const QModelIndex& parent, int first, int last) { - // TODO: some day... maybe - Q_UNUSED(parent) - Q_UNUSED(first) - Q_UNUSED(last) + // TODO: some day... maybe + Q_UNUSED(parent) + Q_UNUSED(first) + Q_UNUSED(last) } void LogView::scrollToBottom() { - m_scrolling = false; - verticalScrollBar()->setSliderPosition(verticalScrollBar()->maximum()); + m_scrolling = false; + verticalScrollBar()->setSliderPosition(verticalScrollBar()->maximum()); } void LogView::findNext(const QString& what, bool reverse) { - find(what, reverse ? QTextDocument::FindFlag::FindBackward : QTextDocument::FindFlag(0)); + find(what, reverse ? QTextDocument::FindFlag::FindBackward : QTextDocument::FindFlag(0)); } diff --git a/application/widgets/LogView.h b/application/widgets/LogView.h index bb6747cd..3143360a 100644 --- a/application/widgets/LogView.h +++ b/application/widgets/LogView.h @@ -6,31 +6,31 @@ class QAbstractItemModel; class LogView: public QPlainTextEdit { - Q_OBJECT + Q_OBJECT public: - explicit LogView(QWidget *parent = nullptr); - virtual ~LogView(); + explicit LogView(QWidget *parent = nullptr); + virtual ~LogView(); - virtual void setModel(QAbstractItemModel *model); - QAbstractItemModel *model() const; + virtual void setModel(QAbstractItemModel *model); + QAbstractItemModel *model() const; public slots: - void setWordWrap(bool wrapping); - void findNext(const QString & what, bool reverse); - void scrollToBottom(); + void setWordWrap(bool wrapping); + void findNext(const QString & what, bool reverse); + void scrollToBottom(); protected slots: - void repopulate(); - // note: this supports only appending - void rowsInserted(const QModelIndex &parent, int first, int last); - void rowsAboutToBeInserted(const QModelIndex &parent, int first, int last); - // note: this supports only removing from front - void rowsRemoved(const QModelIndex &parent, int first, int last); - void modelDestroyed(QObject * model); + void repopulate(); + // note: this supports only appending + void rowsInserted(const QModelIndex &parent, int first, int last); + void rowsAboutToBeInserted(const QModelIndex &parent, int first, int last); + // note: this supports only removing from front + void rowsRemoved(const QModelIndex &parent, int first, int last); + void modelDestroyed(QObject * model); protected: - QAbstractItemModel *m_model = nullptr; - QTextCharFormat *m_defaultFormat = nullptr; - bool m_scroll = false; - bool m_scrolling = false; + QAbstractItemModel *m_model = nullptr; + QTextCharFormat *m_defaultFormat = nullptr; + bool m_scroll = false; + bool m_scrolling = false; }; diff --git a/application/widgets/MCModInfoFrame.cpp b/application/widgets/MCModInfoFrame.cpp index 629c17e7..577b32a7 100644 --- a/application/widgets/MCModInfoFrame.cpp +++ b/application/widgets/MCModInfoFrame.cpp @@ -1,4 +1,4 @@ -/* Copyright 2013-2018 MultiMC Contributors +/* Copyright 2013-2019 MultiMC Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,145 +22,145 @@ void MCModInfoFrame::updateWithMod(Mod &m) { - if (m.type() == m.MOD_FOLDER) - { - clear(); - return; - } + if (m.type() == m.MOD_FOLDER) + { + clear(); + return; + } - QString text = ""; - QString name = ""; - if (m.name().isEmpty()) - name = m.mmc_id(); - else - name = m.name(); + QString text = ""; + QString name = ""; + if (m.name().isEmpty()) + name = m.mmc_id(); + else + name = m.name(); - if (m.homeurl().isEmpty()) - text = name; - else - text = "" + name + ""; - if (!m.authors().isEmpty()) - text += " by " + m.authors(); + if (m.homeurl().isEmpty()) + text = name; + else + text = "" + name + ""; + if (!m.authors().isEmpty()) + text += " by " + m.authors().join(", "); - setModText(text); + setModText(text); - if (m.description().isEmpty()) - { - setModDescription(QString()); - } - else - { - setModDescription(m.description()); - } + if (m.description().isEmpty()) + { + setModDescription(QString()); + } + else + { + setModDescription(m.description()); + } } void MCModInfoFrame::clear() { - setModText(QString()); - setModDescription(QString()); + setModText(QString()); + setModDescription(QString()); } MCModInfoFrame::MCModInfoFrame(QWidget *parent) : - QFrame(parent), - ui(new Ui::MCModInfoFrame) + QFrame(parent), + ui(new Ui::MCModInfoFrame) { - ui->setupUi(this); - ui->label_ModDescription->setHidden(true); - ui->label_ModText->setHidden(true); - updateHiddenState(); + ui->setupUi(this); + ui->label_ModDescription->setHidden(true); + ui->label_ModText->setHidden(true); + updateHiddenState(); } MCModInfoFrame::~MCModInfoFrame() { - delete ui; + delete ui; } void MCModInfoFrame::updateHiddenState() { - if(ui->label_ModDescription->isHidden() && ui->label_ModText->isHidden()) - { - setHidden(true); - } - else - { - setHidden(false); - } + if(ui->label_ModDescription->isHidden() && ui->label_ModText->isHidden()) + { + setHidden(true); + } + else + { + setHidden(false); + } } void MCModInfoFrame::setModText(QString text) { - if(text.isEmpty()) - { - ui->label_ModText->setHidden(true); - } - else - { - ui->label_ModText->setText(text); - ui->label_ModText->setHidden(false); - } - updateHiddenState(); + if(text.isEmpty()) + { + ui->label_ModText->setHidden(true); + } + else + { + ui->label_ModText->setText(text); + ui->label_ModText->setHidden(false); + } + updateHiddenState(); } void MCModInfoFrame::setModDescription(QString text) { - if(text.isEmpty()) - { - ui->label_ModDescription->setHidden(true); - updateHiddenState(); - return; - } - else - { - ui->label_ModDescription->setHidden(false); - updateHiddenState(); - } - ui->label_ModDescription->setToolTip(""); - QString intermediatetext = text.trimmed(); - bool prev(false); - QChar rem('\n'); - QString finaltext; - finaltext.reserve(intermediatetext.size()); - foreach(const QChar& c, intermediatetext) - { - if(c == rem && prev){ - continue; - } - prev = c == rem; - finaltext += c; - } - QString labeltext; - labeltext.reserve(300); - if(finaltext.length() > 290) - { - ui->label_ModDescription->setOpenExternalLinks(false); - ui->label_ModDescription->setTextFormat(Qt::TextFormat::RichText); - desc = text; - labeltext.append("" + finaltext.left(287) + "..."); - QObject::connect(ui->label_ModDescription, &QLabel::linkActivated, this, &MCModInfoFrame::modDescEllipsisHandler); - } - else - { - ui->label_ModDescription->setTextFormat(Qt::TextFormat::PlainText); - labeltext.append(finaltext); - } - ui->label_ModDescription->setText(labeltext); + if(text.isEmpty()) + { + ui->label_ModDescription->setHidden(true); + updateHiddenState(); + return; + } + else + { + ui->label_ModDescription->setHidden(false); + updateHiddenState(); + } + ui->label_ModDescription->setToolTip(""); + QString intermediatetext = text.trimmed(); + bool prev(false); + QChar rem('\n'); + QString finaltext; + finaltext.reserve(intermediatetext.size()); + foreach(const QChar& c, intermediatetext) + { + if(c == rem && prev){ + continue; + } + prev = c == rem; + finaltext += c; + } + QString labeltext; + labeltext.reserve(300); + if(finaltext.length() > 290) + { + ui->label_ModDescription->setOpenExternalLinks(false); + ui->label_ModDescription->setTextFormat(Qt::TextFormat::RichText); + desc = text; + labeltext.append("" + finaltext.left(287) + "..."); + QObject::connect(ui->label_ModDescription, &QLabel::linkActivated, this, &MCModInfoFrame::modDescEllipsisHandler); + } + else + { + ui->label_ModDescription->setTextFormat(Qt::TextFormat::PlainText); + labeltext.append(finaltext); + } + ui->label_ModDescription->setText(labeltext); } void MCModInfoFrame::modDescEllipsisHandler(const QString &link) { - if(!currentBox) - { - currentBox = CustomMessageBox::selectable(this, QString(), desc); - connect(currentBox, &QMessageBox::finished, this, &MCModInfoFrame::boxClosed); - currentBox->show(); - } - else - { - currentBox->setText(desc); - } + if(!currentBox) + { + currentBox = CustomMessageBox::selectable(this, QString(), desc); + connect(currentBox, &QMessageBox::finished, this, &MCModInfoFrame::boxClosed); + currentBox->show(); + } + else + { + currentBox->setText(desc); + } } void MCModInfoFrame::boxClosed(int result) { - currentBox = nullptr; + currentBox = nullptr; } diff --git a/application/widgets/MCModInfoFrame.h b/application/widgets/MCModInfoFrame.h index 6bcd345c..51aa4489 100644 --- a/application/widgets/MCModInfoFrame.h +++ b/application/widgets/MCModInfoFrame.h @@ -1,4 +1,4 @@ -/* Copyright 2013-2018 MultiMC Contributors +/* Copyright 2013-2019 MultiMC Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,7 +16,7 @@ #pragma once #include -#include "minecraft/Mod.h" +#include "minecraft/mod/Mod.h" namespace Ui { @@ -25,28 +25,28 @@ class MCModInfoFrame; class MCModInfoFrame : public QFrame { - Q_OBJECT + Q_OBJECT public: - explicit MCModInfoFrame(QWidget *parent = 0); - ~MCModInfoFrame(); + explicit MCModInfoFrame(QWidget *parent = 0); + ~MCModInfoFrame(); - void setModText(QString text); - void setModDescription(QString text); + void setModText(QString text); + void setModDescription(QString text); - void updateWithMod(Mod &m); - void clear(); + void updateWithMod(Mod &m); + void clear(); public slots: - void modDescEllipsisHandler(const QString& link ); - void boxClosed(int result); + void modDescEllipsisHandler(const QString& link ); + void boxClosed(int result); private: - void updateHiddenState(); + void updateHiddenState(); private: - Ui::MCModInfoFrame *ui; - QString desc; - class QMessageBox * currentBox = nullptr; + Ui::MCModInfoFrame *ui; + QString desc; + class QMessageBox * currentBox = nullptr; }; diff --git a/application/widgets/ModListView.cpp b/application/widgets/ModListView.cpp index 96e8d91b..99972a40 100644 --- a/application/widgets/ModListView.cpp +++ b/application/widgets/ModListView.cpp @@ -1,4 +1,4 @@ -/* Copyright 2013-2018 MultiMC Contributors +/* Copyright 2013-2019 MultiMC Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,46 +21,46 @@ #include ModListView::ModListView ( QWidget* parent ) - :QTreeView ( parent ) + :QTreeView ( parent ) { - setAllColumnsShowFocus ( true ); - setExpandsOnDoubleClick ( false ); - setRootIsDecorated ( false ); - setSortingEnabled ( true ); - setAlternatingRowColors ( true ); - setSelectionMode ( QAbstractItemView::ExtendedSelection ); - setHeaderHidden ( false ); - setSelectionBehavior(QAbstractItemView::SelectRows); - setVerticalScrollBarPolicy ( Qt::ScrollBarAlwaysOn ); - setHorizontalScrollBarPolicy ( Qt::ScrollBarAsNeeded ); - setDropIndicatorShown(true); - setDragEnabled(true); - setDragDropMode(QAbstractItemView::DropOnly); - viewport()->setAcceptDrops(true); + setAllColumnsShowFocus ( true ); + setExpandsOnDoubleClick ( false ); + setRootIsDecorated ( false ); + setSortingEnabled ( true ); + setAlternatingRowColors ( true ); + setSelectionMode ( QAbstractItemView::ExtendedSelection ); + setHeaderHidden ( false ); + setSelectionBehavior(QAbstractItemView::SelectRows); + setVerticalScrollBarPolicy ( Qt::ScrollBarAlwaysOn ); + setHorizontalScrollBarPolicy ( Qt::ScrollBarAsNeeded ); + setDropIndicatorShown(true); + setDragEnabled(true); + setDragDropMode(QAbstractItemView::DropOnly); + viewport()->setAcceptDrops(true); } void ModListView::setModel ( QAbstractItemModel* model ) { - QTreeView::setModel ( model ); - auto head = header(); - head->setStretchLastSection(false); - // HACK: this is true for the checkbox column of mod lists - auto string = model->headerData(0,head->orientation()).toString(); - if(head->count() < 1) - { - return; - } - if(!string.size()) - { - head->setSectionResizeMode(0, QHeaderView::ResizeToContents); - head->setSectionResizeMode(1, QHeaderView::Stretch); - for(int i = 2; i < head->count(); i++) - head->setSectionResizeMode(i, QHeaderView::ResizeToContents); - } - else - { - head->setSectionResizeMode(0, QHeaderView::Stretch); - for(int i = 1; i < head->count(); i++) - head->setSectionResizeMode(i, QHeaderView::ResizeToContents); - } + QTreeView::setModel ( model ); + auto head = header(); + head->setStretchLastSection(false); + // HACK: this is true for the checkbox column of mod lists + auto string = model->headerData(0,head->orientation()).toString(); + if(head->count() < 1) + { + return; + } + if(!string.size()) + { + head->setSectionResizeMode(0, QHeaderView::ResizeToContents); + head->setSectionResizeMode(1, QHeaderView::Stretch); + for(int i = 2; i < head->count(); i++) + head->setSectionResizeMode(i, QHeaderView::ResizeToContents); + } + else + { + head->setSectionResizeMode(0, QHeaderView::Stretch); + for(int i = 1; i < head->count(); i++) + head->setSectionResizeMode(i, QHeaderView::ResizeToContents); + } } diff --git a/application/widgets/ModListView.h b/application/widgets/ModListView.h index baca23f4..5a07e868 100644 --- a/application/widgets/ModListView.h +++ b/application/widgets/ModListView.h @@ -1,4 +1,4 @@ -/* Copyright 2013-2018 MultiMC Contributors +/* Copyright 2013-2019 MultiMC Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,12 +16,10 @@ #pragma once #include -class Mod; - class ModListView: public QTreeView { - Q_OBJECT + Q_OBJECT public: - explicit ModListView ( QWidget* parent = 0 ); - virtual void setModel ( QAbstractItemModel* model ); + explicit ModListView ( QWidget* parent = 0 ); + virtual void setModel ( QAbstractItemModel* model ); }; diff --git a/application/widgets/PageContainer.cpp b/application/widgets/PageContainer.cpp index 98de57e8..376e119b 100644 --- a/application/widgets/PageContainer.cpp +++ b/application/widgets/PageContainer.cpp @@ -1,4 +1,4 @@ -/* Copyright 2013-2018 MultiMC Contributors +/* Copyright 2013-2019 MultiMC Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,196 +36,204 @@ class PageEntryFilterModel : public QSortFilterProxyModel { public: - explicit PageEntryFilterModel(QObject *parent = 0) : QSortFilterProxyModel(parent) - { - } + explicit PageEntryFilterModel(QObject *parent = 0) : QSortFilterProxyModel(parent) + { + } protected: - bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const - { - const QString pattern = filterRegExp().pattern(); - const auto model = static_cast(sourceModel()); - const auto page = model->pages().at(sourceRow); - if (!page->shouldDisplay()) - return false; - // Regular contents check, then check page-filter. - return QSortFilterProxyModel::filterAcceptsRow(sourceRow, sourceParent); - } + bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const + { + const QString pattern = filterRegExp().pattern(); + const auto model = static_cast(sourceModel()); + const auto page = model->pages().at(sourceRow); + if (!page->shouldDisplay()) + return false; + // Regular contents check, then check page-filter. + return QSortFilterProxyModel::filterAcceptsRow(sourceRow, sourceParent); + } }; PageContainer::PageContainer(BasePageProvider *pageProvider, QString defaultId, - QWidget *parent) - : QWidget(parent) + QWidget *parent) + : QWidget(parent) { - createUI(); - m_model = new PageModel(this); - m_proxyModel = new PageEntryFilterModel(this); - int counter = 0; - auto pages = pageProvider->getPages(); - for (auto page : pages) - { - page->stackIndex = m_pageStack->addWidget(dynamic_cast(page)); - page->listIndex = counter; - page->setParentContainer(this); - counter++; - } - m_model->setPages(pages); - - m_proxyModel->setSourceModel(m_model); - m_proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive); - - m_pageList->setIconSize(QSize(pageIconSize, pageIconSize)); - m_pageList->setSelectionMode(QAbstractItemView::SingleSelection); - m_pageList->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); - m_pageList->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents); - m_pageList->setModel(m_proxyModel); - connect(m_pageList->selectionModel(), SIGNAL(currentRowChanged(QModelIndex, QModelIndex)), - this, SLOT(currentChanged(QModelIndex))); - m_pageStack->setStackingMode(QStackedLayout::StackOne); - m_pageList->setFocus(); - selectPage(defaultId); + createUI(); + m_model = new PageModel(this); + m_proxyModel = new PageEntryFilterModel(this); + int counter = 0; + auto pages = pageProvider->getPages(); + for (auto page : pages) + { + page->stackIndex = m_pageStack->addWidget(dynamic_cast(page)); + page->listIndex = counter; + page->setParentContainer(this); + counter++; + } + m_model->setPages(pages); + + m_proxyModel->setSourceModel(m_model); + m_proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive); + + m_pageList->setIconSize(QSize(pageIconSize, pageIconSize)); + m_pageList->setSelectionMode(QAbstractItemView::SingleSelection); + m_pageList->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); + m_pageList->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents); + m_pageList->setModel(m_proxyModel); + connect(m_pageList->selectionModel(), SIGNAL(currentRowChanged(QModelIndex, QModelIndex)), + this, SLOT(currentChanged(QModelIndex))); + m_pageStack->setStackingMode(QStackedLayout::StackOne); + m_pageList->setFocus(); + selectPage(defaultId); } bool PageContainer::selectPage(QString pageId) { - // now find what we want to have selected... - auto page = m_model->findPageEntryById(pageId); - QModelIndex index; - if (page) - { - index = m_proxyModel->mapFromSource(m_model->index(page->listIndex)); - } - if(!index.isValid()) - { - index = m_proxyModel->index(0, 0); - } - if (index.isValid()) - { - m_pageList->setCurrentIndex(index); - return true; - } - return false; + // now find what we want to have selected... + auto page = m_model->findPageEntryById(pageId); + QModelIndex index; + if (page) + { + index = m_proxyModel->mapFromSource(m_model->index(page->listIndex)); + } + if(!index.isValid()) + { + index = m_proxyModel->index(0, 0); + } + if (index.isValid()) + { + m_pageList->setCurrentIndex(index); + return true; + } + return false; } void PageContainer::refreshContainer() { - m_proxyModel->invalidate(); - if(!m_currentPage->shouldDisplay()) - { - auto index = m_proxyModel->index(0, 0); - if(index.isValid()) - { - m_pageList->setCurrentIndex(index); - } - else - { - // FIXME: unhandled corner case: what to do when there's no page to select? - } - } + m_proxyModel->invalidate(); + if(!m_currentPage->shouldDisplay()) + { + auto index = m_proxyModel->index(0, 0); + if(index.isValid()) + { + m_pageList->setCurrentIndex(index); + } + else + { + // FIXME: unhandled corner case: what to do when there's no page to select? + } + } } void PageContainer::createUI() { - m_pageStack = new QStackedLayout; - m_pageList = new PageView; - m_header = new QLabel(); - m_iconHeader = new IconLabel(this, QIcon(), QSize(24, 24)); - - QFont headerLabelFont = m_header->font(); - headerLabelFont.setBold(true); - const int pointSize = headerLabelFont.pointSize(); - if (pointSize > 0) - headerLabelFont.setPointSize(pointSize + 2); - m_header->setFont(headerLabelFont); - - QHBoxLayout *headerHLayout = new QHBoxLayout; - const int leftMargin = MMC->style()->pixelMetric(QStyle::PM_LayoutLeftMargin); - headerHLayout->addSpacerItem( - new QSpacerItem(leftMargin, 0, QSizePolicy::Fixed, QSizePolicy::Ignored)); - headerHLayout->addWidget(m_header); - headerHLayout->addSpacerItem( - new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Ignored)); - headerHLayout->addWidget(m_iconHeader); - const int rightMargin = MMC->style()->pixelMetric(QStyle::PM_LayoutRightMargin); - headerHLayout->addSpacerItem( - new QSpacerItem(rightMargin, 0, QSizePolicy::Fixed, QSizePolicy::Ignored)); - - m_pageStack->setMargin(0); - m_pageStack->addWidget(new QWidget(this)); - - m_layout = new QGridLayout; - m_layout->addLayout(headerHLayout, 0, 1, 1, 1); - m_layout->addWidget(m_pageList, 0, 0, 2, 1); - m_layout->addLayout(m_pageStack, 1, 1, 1, 1); - m_layout->setColumnStretch(1, 4); - setLayout(m_layout); + m_pageStack = new QStackedLayout; + m_pageList = new PageView; + m_header = new QLabel(); + m_iconHeader = new IconLabel(this, QIcon(), QSize(24, 24)); + + QFont headerLabelFont = m_header->font(); + headerLabelFont.setBold(true); + const int pointSize = headerLabelFont.pointSize(); + if (pointSize > 0) + headerLabelFont.setPointSize(pointSize + 2); + m_header->setFont(headerLabelFont); + + QHBoxLayout *headerHLayout = new QHBoxLayout; + const int leftMargin = MMC->style()->pixelMetric(QStyle::PM_LayoutLeftMargin); + headerHLayout->addSpacerItem(new QSpacerItem(leftMargin, 0, QSizePolicy::Fixed, QSizePolicy::Ignored)); + headerHLayout->addWidget(m_header); + headerHLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Ignored)); + headerHLayout->addWidget(m_iconHeader); + const int rightMargin = MMC->style()->pixelMetric(QStyle::PM_LayoutRightMargin); + headerHLayout->addSpacerItem(new QSpacerItem(rightMargin, 0, QSizePolicy::Fixed, QSizePolicy::Ignored)); + headerHLayout->setContentsMargins(0, 6, 0, 0); + + m_pageStack->setMargin(0); + m_pageStack->addWidget(new QWidget(this)); + + m_layout = new QGridLayout; + m_layout->addLayout(headerHLayout, 0, 1, 1, 1); + m_layout->addWidget(m_pageList, 0, 0, 2, 1); + m_layout->addLayout(m_pageStack, 1, 1, 1, 1); + m_layout->setColumnStretch(1, 4); + m_layout->setContentsMargins(0,0,0,6); + setLayout(m_layout); } void PageContainer::addButtons(QWidget *buttons) { - m_layout->addWidget(buttons, 2, 0, 1, 2); + m_layout->addWidget(buttons, 2, 0, 1, 2); } void PageContainer::addButtons(QLayout *buttons) { - m_layout->addLayout(buttons, 2, 0, 1, 2); + m_layout->addLayout(buttons, 2, 0, 1, 2); } void PageContainer::showPage(int row) { - if (m_currentPage) - { - m_currentPage->closed(); - } - if (row != -1) - { - m_currentPage = m_model->pages().at(row); - } - else - { - m_currentPage = nullptr; - } - if (m_currentPage) - { - m_pageStack->setCurrentIndex(m_currentPage->stackIndex); - m_header->setText(m_currentPage->displayName()); - m_iconHeader->setIcon(m_currentPage->icon()); - m_currentPage->opened(); - } - else - { - m_pageStack->setCurrentIndex(0); - m_header->setText(QString()); - m_iconHeader->setIcon(MMC->getThemedIcon("bug")); - } + if (m_currentPage) + { + m_currentPage->closed(); + } + if (row != -1) + { + m_currentPage = m_model->pages().at(row); + } + else + { + m_currentPage = nullptr; + } + if (m_currentPage) + { + m_pageStack->setCurrentIndex(m_currentPage->stackIndex); + m_header->setText(m_currentPage->displayName()); + m_iconHeader->setIcon(m_currentPage->icon()); + m_currentPage->opened(); + } + else + { + m_pageStack->setCurrentIndex(0); + m_header->setText(QString()); + m_iconHeader->setIcon(MMC->getThemedIcon("bug")); + } } void PageContainer::help() { - if (m_currentPage) - { - QString pageId = m_currentPage->helpPage(); - if (pageId.isEmpty()) - return; - DesktopServices::openUrl(QUrl("https://github.com/MultiMC/MultiMC5/wiki/" + pageId)); - } + if (m_currentPage) + { + QString pageId = m_currentPage->helpPage(); + if (pageId.isEmpty()) + return; + DesktopServices::openUrl(QUrl("https://github.com/MultiMC/MultiMC5/wiki/" + pageId)); + } } void PageContainer::currentChanged(const QModelIndex ¤t) { - showPage(current.isValid() ? m_proxyModel->mapToSource(current).row() : -1); + showPage(current.isValid() ? m_proxyModel->mapToSource(current).row() : -1); } bool PageContainer::prepareToClose() { - for (auto page : m_model->pages()) - { - if (!page->apply()) - return false; - } - if (m_currentPage) - { - m_currentPage->closed(); - } - return true; + if(!saveAll()) + { + return false; + } + if (m_currentPage) + { + m_currentPage->closed(); + } + return true; +} + +bool PageContainer::saveAll() +{ + for (auto page : m_model->pages()) + { + if (!page->apply()) + return false; + } + return true; } diff --git a/application/widgets/PageContainer.h b/application/widgets/PageContainer.h index ea9f8ce1..925f4ba3 100644 --- a/application/widgets/PageContainer.h +++ b/application/widgets/PageContainer.h @@ -1,4 +1,4 @@ -/* Copyright 2013-2018 MultiMC Contributors +/* Copyright 2013-2019 MultiMC Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,56 +33,57 @@ class QGridLayout; class PageContainer : public QWidget, public BasePageContainer { - Q_OBJECT + Q_OBJECT public: - explicit PageContainer(BasePageProvider *pageProvider, QString defaultId = QString(), - QWidget *parent = 0); - virtual ~PageContainer() {} + explicit PageContainer(BasePageProvider *pageProvider, QString defaultId = QString(), + QWidget *parent = 0); + virtual ~PageContainer() {} - void addButtons(QWidget * buttons); - void addButtons(QLayout * buttons); - /* - * Save any unsaved state and prepare to be closed. - * @return true if everything can be saved, false if there is something that requires attention - */ - bool prepareToClose(); + void addButtons(QWidget * buttons); + void addButtons(QLayout * buttons); + /* + * Save any unsaved state and prepare to be closed. + * @return true if everything can be saved, false if there is something that requires attention + */ + bool prepareToClose(); + bool saveAll(); - /* request close - used by individual pages */ - bool requestClose() override - { - if(m_container) - { - return m_container->requestClose(); - } - return false; - } + /* request close - used by individual pages */ + bool requestClose() override + { + if(m_container) + { + return m_container->requestClose(); + } + return false; + } - virtual bool selectPage(QString pageId) override; + virtual bool selectPage(QString pageId) override; - void refreshContainer() override; - virtual void setParentContainer(BasePageContainer * container) - { - m_container = container; - }; + void refreshContainer() override; + virtual void setParentContainer(BasePageContainer * container) + { + m_container = container; + }; private: - void createUI(); + void createUI(); public slots: - void help(); + void help(); private slots: - void currentChanged(const QModelIndex ¤t); - void showPage(int row); + void currentChanged(const QModelIndex ¤t); + void showPage(int row); private: - BasePageContainer * m_container = nullptr; - BasePage * m_currentPage = 0; - QSortFilterProxyModel *m_proxyModel; - PageModel *m_model; - QStackedLayout *m_pageStack; - QListView *m_pageList; - QLabel *m_header; - IconLabel *m_iconHeader; - QGridLayout *m_layout; + BasePageContainer * m_container = nullptr; + BasePage * m_currentPage = 0; + QSortFilterProxyModel *m_proxyModel; + PageModel *m_model; + QStackedLayout *m_pageStack; + QListView *m_pageList; + QLabel *m_header; + IconLabel *m_iconHeader; + QGridLayout *m_layout; }; diff --git a/application/widgets/PageContainer_p.h b/application/widgets/PageContainer_p.h index ed8171f1..4a5a9239 100644 --- a/application/widgets/PageContainer_p.h +++ b/application/widgets/PageContainer_p.h @@ -1,4 +1,4 @@ -/* Copyright 2013-2018 MultiMC Contributors +/* Copyright 2013-2019 MultiMC Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,98 +26,98 @@ const int pageIconSize = 24; class PageViewDelegate : public QStyledItemDelegate { public: - PageViewDelegate(QObject *parent) : QStyledItemDelegate(parent) - { - } - QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const - { - QSize size = QStyledItemDelegate::sizeHint(option, index); - size.setHeight(qMax(size.height(), 32)); - return size; - } + PageViewDelegate(QObject *parent) : QStyledItemDelegate(parent) + { + } + QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const + { + QSize size = QStyledItemDelegate::sizeHint(option, index); + size.setHeight(qMax(size.height(), 32)); + return size; + } }; class PageModel : public QAbstractListModel { public: - PageModel(QObject *parent = 0) : QAbstractListModel(parent) - { - QPixmap empty(pageIconSize, pageIconSize); - empty.fill(Qt::transparent); - m_emptyIcon = QIcon(empty); - } - virtual ~PageModel() {} + PageModel(QObject *parent = 0) : QAbstractListModel(parent) + { + QPixmap empty(pageIconSize, pageIconSize); + empty.fill(Qt::transparent); + m_emptyIcon = QIcon(empty); + } + virtual ~PageModel() {} - int rowCount(const QModelIndex &parent = QModelIndex()) const - { - return parent.isValid() ? 0 : m_pages.size(); - } - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const - { - switch (role) - { - case Qt::DisplayRole: - return m_pages.at(index.row())->displayName(); - case Qt::DecorationRole: - { - QIcon icon = m_pages.at(index.row())->icon(); - if (icon.isNull()) - icon = m_emptyIcon; - // HACK: fixes icon stretching on windows. TODO: report Qt bug for this - return QIcon(icon.pixmap(QSize(48,48))); - } - } - return QVariant(); - } + int rowCount(const QModelIndex &parent = QModelIndex()) const + { + return parent.isValid() ? 0 : m_pages.size(); + } + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const + { + switch (role) + { + case Qt::DisplayRole: + return m_pages.at(index.row())->displayName(); + case Qt::DecorationRole: + { + QIcon icon = m_pages.at(index.row())->icon(); + if (icon.isNull()) + icon = m_emptyIcon; + // HACK: fixes icon stretching on windows. TODO: report Qt bug for this + return QIcon(icon.pixmap(QSize(48,48))); + } + } + return QVariant(); + } - void setPages(const QList &pages) - { - beginResetModel(); - m_pages = pages; - endResetModel(); - } - const QList &pages() const - { - return m_pages; - } + void setPages(const QList &pages) + { + beginResetModel(); + m_pages = pages; + endResetModel(); + } + const QList &pages() const + { + return m_pages; + } - BasePage * findPageEntryById(QString id) - { - for(auto page: m_pages) - { - if (page->id() == id) - return page; - } - return nullptr; - } + BasePage * findPageEntryById(QString id) + { + for(auto page: m_pages) + { + if (page->id() == id) + return page; + } + return nullptr; + } - QList m_pages; - QIcon m_emptyIcon; + QList m_pages; + QIcon m_emptyIcon; }; class PageView : public QListView { public: - PageView(QWidget *parent = 0) : QListView(parent) - { - setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Expanding); - setItemDelegate(new PageViewDelegate(this)); - setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - } + PageView(QWidget *parent = 0) : QListView(parent) + { + setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Expanding); + setItemDelegate(new PageViewDelegate(this)); + setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + } - virtual QSize sizeHint() const - { - int width = sizeHintForColumn(0) + frameWidth() * 2 + 5; - if (verticalScrollBar()->isVisible()) - width += verticalScrollBar()->width(); - return QSize(width, 100); - } + virtual QSize sizeHint() const + { + int width = sizeHintForColumn(0) + frameWidth() * 2 + 5; + if (verticalScrollBar()->isVisible()) + width += verticalScrollBar()->width(); + return QSize(width, 100); + } - virtual bool eventFilter(QObject *obj, QEvent *event) - { - if (obj == verticalScrollBar() && - (event->type() == QEvent::Show || event->type() == QEvent::Hide)) - updateGeometry(); - return QListView::eventFilter(obj, event); - } + virtual bool eventFilter(QObject *obj, QEvent *event) + { + if (obj == verticalScrollBar() && + (event->type() == QEvent::Show || event->type() == QEvent::Hide)) + updateGeometry(); + return QListView::eventFilter(obj, event); + } }; diff --git a/application/widgets/ProgressWidget.cpp b/application/widgets/ProgressWidget.cpp index fab099a9..911e555d 100644 --- a/application/widgets/ProgressWidget.cpp +++ b/application/widgets/ProgressWidget.cpp @@ -9,65 +9,65 @@ #include "tasks/Task.h" ProgressWidget::ProgressWidget(QWidget *parent) - : QWidget(parent) + : QWidget(parent) { - m_label = new QLabel(this); - m_label->setWordWrap(true); - m_bar = new QProgressBar(this); - m_bar->setMinimum(0); - m_bar->setMaximum(100); - QVBoxLayout *layout = new QVBoxLayout(this); - layout->addWidget(m_label); - layout->addWidget(m_bar); - layout->addStretch(); - setLayout(layout); + m_label = new QLabel(this); + m_label->setWordWrap(true); + m_bar = new QProgressBar(this); + m_bar->setMinimum(0); + m_bar->setMaximum(100); + QVBoxLayout *layout = new QVBoxLayout(this); + layout->addWidget(m_label); + layout->addWidget(m_bar); + layout->addStretch(); + setLayout(layout); } void ProgressWidget::start(std::shared_ptr task) { - if (m_task) - { - disconnect(m_task.get(), 0, this, 0); - } - m_task = task; - connect(m_task.get(), &Task::finished, this, &ProgressWidget::handleTaskFinish); - connect(m_task.get(), &Task::status, this, &ProgressWidget::handleTaskStatus); - connect(m_task.get(), &Task::progress, this, &ProgressWidget::handleTaskProgress); - connect(m_task.get(), &Task::destroyed, this, &ProgressWidget::taskDestroyed); - if (!m_task->isRunning()) - { - QMetaObject::invokeMethod(m_task.get(), "start", Qt::QueuedConnection); - } + if (m_task) + { + disconnect(m_task.get(), 0, this, 0); + } + m_task = task; + connect(m_task.get(), &Task::finished, this, &ProgressWidget::handleTaskFinish); + connect(m_task.get(), &Task::status, this, &ProgressWidget::handleTaskStatus); + connect(m_task.get(), &Task::progress, this, &ProgressWidget::handleTaskProgress); + connect(m_task.get(), &Task::destroyed, this, &ProgressWidget::taskDestroyed); + if (!m_task->isRunning()) + { + QMetaObject::invokeMethod(m_task.get(), "start", Qt::QueuedConnection); + } } bool ProgressWidget::exec(std::shared_ptr task) { - QEventLoop loop; - connect(task.get(), &Task::finished, &loop, &QEventLoop::quit); - start(task); - if (task->isRunning()) - { - loop.exec(); - } - return task->wasSuccessful(); + QEventLoop loop; + connect(task.get(), &Task::finished, &loop, &QEventLoop::quit); + start(task); + if (task->isRunning()) + { + loop.exec(); + } + return task->wasSuccessful(); } void ProgressWidget::handleTaskFinish() { - if (!m_task->wasSuccessful()) - { - m_label->setText(m_task->failReason()); - } + if (!m_task->wasSuccessful()) + { + m_label->setText(m_task->failReason()); + } } void ProgressWidget::handleTaskStatus(const QString &status) { - m_label->setText(status); + m_label->setText(status); } void ProgressWidget::handleTaskProgress(qint64 current, qint64 total) { - m_bar->setMaximum(total); - m_bar->setValue(current); + m_bar->setMaximum(total); + m_bar->setValue(current); } void ProgressWidget::taskDestroyed() { - m_task = nullptr; + m_task = nullptr; } diff --git a/application/widgets/ProgressWidget.h b/application/widgets/ProgressWidget.h index 08d8a157..fa67748a 100644 --- a/application/widgets/ProgressWidget.h +++ b/application/widgets/ProgressWidget.h @@ -11,22 +11,22 @@ class QLabel; class ProgressWidget : public QWidget { - Q_OBJECT + Q_OBJECT public: - explicit ProgressWidget(QWidget *parent = nullptr); + explicit ProgressWidget(QWidget *parent = nullptr); public slots: - void start(std::shared_ptr task); - bool exec(std::shared_ptr task); + void start(std::shared_ptr task); + bool exec(std::shared_ptr task); private slots: - void handleTaskFinish(); - void handleTaskStatus(const QString &status); - void handleTaskProgress(qint64 current, qint64 total); - void taskDestroyed(); + void handleTaskFinish(); + void handleTaskStatus(const QString &status); + void handleTaskProgress(qint64 current, qint64 total); + void taskDestroyed(); private: - QLabel *m_label; - QProgressBar *m_bar; - std::shared_ptr m_task; + QLabel *m_label; + QProgressBar *m_bar; + std::shared_ptr m_task; }; diff --git a/application/widgets/ServerStatus.cpp b/application/widgets/ServerStatus.cpp index f1963b68..a7016c0c 100644 --- a/application/widgets/ServerStatus.cpp +++ b/application/widgets/ServerStatus.cpp @@ -15,80 +15,80 @@ class ClickableLabel : public QLabel { - Q_OBJECT + Q_OBJECT public: - ClickableLabel(QWidget *parent) : QLabel(parent) - { - setCursor(Qt::PointingHandCursor); - } + ClickableLabel(QWidget *parent) : QLabel(parent) + { + setCursor(Qt::PointingHandCursor); + } - ~ClickableLabel(){}; + ~ClickableLabel(){}; signals: - void clicked(); + void clicked(); protected: - void mousePressEvent(QMouseEvent *event) - { - emit clicked(); - } + void mousePressEvent(QMouseEvent *event) + { + emit clicked(); + } }; class ClickableIconLabel : public IconLabel { - Q_OBJECT + Q_OBJECT public: - ClickableIconLabel(QWidget *parent, QIcon icon, QSize size) : IconLabel(parent, icon, size) - { - setCursor(Qt::PointingHandCursor); - } + ClickableIconLabel(QWidget *parent, QIcon icon, QSize size) : IconLabel(parent, icon, size) + { + setCursor(Qt::PointingHandCursor); + } - ~ClickableIconLabel(){}; + ~ClickableIconLabel(){}; signals: - void clicked(); + void clicked(); protected: - void mousePressEvent(QMouseEvent *event) - { - emit clicked(); - } + void mousePressEvent(QMouseEvent *event) + { + emit clicked(); + } }; ServerStatus::ServerStatus(QWidget *parent, Qt::WindowFlags f) : QWidget(parent, f) { - layout = new QHBoxLayout(this); - layout->setContentsMargins(0, 0, 0, 0); - goodIcon = MMC->getThemedIcon("status-good"); - yellowIcon = MMC->getThemedIcon("status-yellow"); - badIcon = MMC->getThemedIcon("status-bad"); - - addStatus("authserver.mojang.com", tr("Auth")); - addLine(); - addStatus("sessionserver.mojang.com", tr("Session")); - addLine(); - addStatus("textures.minecraft.net", tr("Skins")); - addLine(); - addStatus("api.mojang.com", tr("API")); - - m_statusRefresh = new QToolButton(this); - m_statusRefresh->setCheckable(true); - m_statusRefresh->setToolButtonStyle(Qt::ToolButtonIconOnly); - m_statusRefresh->setIcon(MMC->getThemedIcon("refresh")); - layout->addWidget(m_statusRefresh); - - setLayout(layout); - - // Start status checker - m_statusChecker.reset(new StatusChecker()); - { - auto reloader = m_statusChecker.get(); - connect(reloader, &StatusChecker::statusChanged, this, &ServerStatus::StatusChanged); - connect(reloader, &StatusChecker::statusLoading, this, &ServerStatus::StatusReloading); - connect(m_statusRefresh, &QAbstractButton::clicked, this, &ServerStatus::reloadStatus); - m_statusChecker->startTimer(60000); - reloadStatus(); - } + layout = new QHBoxLayout(this); + layout->setContentsMargins(0, 0, 0, 0); + goodIcon = MMC->getThemedIcon("status-good"); + yellowIcon = MMC->getThemedIcon("status-yellow"); + badIcon = MMC->getThemedIcon("status-bad"); + + addStatus("authserver.mojang.com", tr("Auth")); + addLine(); + addStatus("sessionserver.mojang.com", tr("Session")); + addLine(); + addStatus("textures.minecraft.net", tr("Skins")); + addLine(); + addStatus("api.mojang.com", tr("API")); + + m_statusRefresh = new QToolButton(this); + m_statusRefresh->setCheckable(true); + m_statusRefresh->setToolButtonStyle(Qt::ToolButtonIconOnly); + m_statusRefresh->setIcon(MMC->getThemedIcon("refresh")); + layout->addWidget(m_statusRefresh); + + setLayout(layout); + + // Start status checker + m_statusChecker.reset(new StatusChecker()); + { + auto reloader = m_statusChecker.get(); + connect(reloader, &StatusChecker::statusChanged, this, &ServerStatus::StatusChanged); + connect(reloader, &StatusChecker::statusLoading, this, &ServerStatus::StatusReloading); + connect(m_statusRefresh, &QAbstractButton::clicked, this, &ServerStatus::reloadStatus); + m_statusChecker->startTimer(60000); + reloadStatus(); + } } ServerStatus::~ServerStatus() @@ -97,83 +97,83 @@ ServerStatus::~ServerStatus() void ServerStatus::reloadStatus() { - m_statusChecker->reloadStatus(); + m_statusChecker->reloadStatus(); } void ServerStatus::addLine() { - layout->addWidget(new LineSeparator(this, Qt::Vertical)); + layout->addWidget(new LineSeparator(this, Qt::Vertical)); } void ServerStatus::addStatus(QString key, QString name) { - { - auto label = new ClickableIconLabel(this, badIcon, QSize(16, 16)); - label->setToolTip(key); - serverLabels[key] = label; - layout->addWidget(label); - connect(label,SIGNAL(clicked()),SLOT(clicked())); - } - { - auto label = new ClickableLabel(this); - label->setText(name); - label->setToolTip(key); - layout->addWidget(label); - connect(label,SIGNAL(clicked()),SLOT(clicked())); - } + { + auto label = new ClickableIconLabel(this, badIcon, QSize(16, 16)); + label->setToolTip(key); + serverLabels[key] = label; + layout->addWidget(label); + connect(label,SIGNAL(clicked()),SLOT(clicked())); + } + { + auto label = new ClickableLabel(this); + label->setText(name); + label->setToolTip(key); + layout->addWidget(label); + connect(label,SIGNAL(clicked()),SLOT(clicked())); + } } void ServerStatus::clicked() { - DesktopServices::openUrl(QUrl("https://help.mojang.com/")); + DesktopServices::openUrl(QUrl("https://help.mojang.com/")); } void ServerStatus::setStatus(QString key, int value) { - if (!serverLabels.contains(key)) - return; - IconLabel *label = serverLabels[key]; - switch(value) - { - case 0: - label->setIcon(goodIcon); - break; - case 1: - label->setIcon(yellowIcon); - break; - default: - case 2: - label->setIcon(badIcon); - break; - } + if (!serverLabels.contains(key)) + return; + IconLabel *label = serverLabels[key]; + switch(value) + { + case 0: + label->setIcon(goodIcon); + break; + case 1: + label->setIcon(yellowIcon); + break; + default: + case 2: + label->setIcon(badIcon); + break; + } } void ServerStatus::StatusChanged(const QMap statusEntries) { - auto convertStatus = [&](QString status)->int - { - if (status == "green") - return 0; - else if (status == "yellow") - return 1; - else if (status == "red") - return 2; - return 2; - } - ; - auto iter = statusEntries.begin(); - while (iter != statusEntries.end()) - { - QString key = iter.key(); - auto value = convertStatus(iter.value()); - setStatus(key, value); - iter++; - } + auto convertStatus = [&](QString status)->int + { + if (status == "green") + return 0; + else if (status == "yellow") + return 1; + else if (status == "red") + return 2; + return 2; + } + ; + auto iter = statusEntries.begin(); + while (iter != statusEntries.end()) + { + QString key = iter.key(); + auto value = convertStatus(iter.value()); + setStatus(key, value); + iter++; + } } void ServerStatus::StatusReloading(bool is_reloading) { - m_statusRefresh->setChecked(is_reloading); + m_statusRefresh->setChecked(is_reloading); } #include "ServerStatus.moc" diff --git a/application/widgets/ServerStatus.h b/application/widgets/ServerStatus.h index 9beb8e4f..e1e70dfb 100644 --- a/application/widgets/ServerStatus.h +++ b/application/widgets/ServerStatus.h @@ -12,29 +12,29 @@ class StatusChecker; class ServerStatus: public QWidget { - Q_OBJECT + Q_OBJECT public: - explicit ServerStatus(QWidget *parent = nullptr, Qt::WindowFlags f = 0); - virtual ~ServerStatus(); + explicit ServerStatus(QWidget *parent = nullptr, Qt::WindowFlags f = 0); + virtual ~ServerStatus(); public slots: - void reloadStatus(); - void StatusChanged(const QMap statuses); - void StatusReloading(bool is_reloading); + void reloadStatus(); + void StatusChanged(const QMap statuses); + void StatusReloading(bool is_reloading); private slots: - void clicked(); + void clicked(); private: /* methods */ - void addLine(); - void addStatus(QString key, QString name); - void setStatus(QString key, int value); + void addLine(); + void addStatus(QString key, QString name); + void setStatus(QString key, int value); private: /* data */ - QHBoxLayout * layout = nullptr; - QToolButton *m_statusRefresh = nullptr; - QMap serverLabels; - QIcon goodIcon; - QIcon yellowIcon; - QIcon badIcon; - std::shared_ptr m_statusChecker; + QHBoxLayout * layout = nullptr; + QToolButton *m_statusRefresh = nullptr; + QMap serverLabels; + QIcon goodIcon; + QIcon yellowIcon; + QIcon badIcon; + std::shared_ptr m_statusChecker; }; diff --git a/application/widgets/VersionListView.cpp b/application/widgets/VersionListView.cpp index 8c80ecf3..09df75b7 100644 --- a/application/widgets/VersionListView.cpp +++ b/application/widgets/VersionListView.cpp @@ -1,4 +1,4 @@ -/* Copyright 2013-2018 MultiMC Contributors +/* Copyright 2013-2019 MultiMC Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,155 +22,140 @@ #include "Common.h" VersionListView::VersionListView(QWidget *parent) - :QTreeView ( parent ) + :QTreeView ( parent ) { - m_emptyString = tr("No versions are currently available."); + m_emptyString = tr("No versions are currently available."); } void VersionListView::rowsInserted(const QModelIndex &parent, int start, int end) { - if(!m_itemCount) - viewport()->update(); - m_itemCount += end-start+1; - QTreeView::rowsInserted(parent, start, end); + m_itemCount += end-start+1; + updateEmptyViewPort(); + QTreeView::rowsInserted(parent, start, end); } void VersionListView::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end) { - m_itemCount -= end-start+1; - if(!m_itemCount) - viewport()->update(); - QTreeView::rowsInserted(parent, start, end); + m_itemCount -= end-start+1; + updateEmptyViewPort(); + QTreeView::rowsInserted(parent, start, end); } void VersionListView::setModel(QAbstractItemModel *model) { - m_itemCount = model->rowCount(); - if(!m_itemCount) - viewport()->update(); - QTreeView::setModel(model); + m_itemCount = model->rowCount(); + updateEmptyViewPort(); + QTreeView::setModel(model); } void VersionListView::reset() { - if(model()) - { - m_itemCount = model()->rowCount(); - } - viewport()->update(); - QTreeView::reset(); + if(model()) + { + m_itemCount = model()->rowCount(); + } + else { + m_itemCount = 0; + } + updateEmptyViewPort(); + QTreeView::reset(); } void VersionListView::setEmptyString(QString emptyString) { - m_emptyString = emptyString; - updateEmptyViewPort(); + m_emptyString = emptyString; + updateEmptyViewPort(); } void VersionListView::setEmptyErrorString(QString emptyErrorString) { - m_emptyErrorString = emptyErrorString; - updateEmptyViewPort(); + m_emptyErrorString = emptyErrorString; + updateEmptyViewPort(); } void VersionListView::setEmptyMode(VersionListView::EmptyMode mode) { - m_emptyMode = mode; - updateEmptyViewPort(); + m_emptyMode = mode; + updateEmptyViewPort(); } void VersionListView::updateEmptyViewPort() { - if(!m_itemCount) - { - viewport()->update(); - } + setAccessibleDescription(currentEmptyString()); + + if(!m_itemCount) + { + viewport()->update(); + } } void VersionListView::paintEvent(QPaintEvent *event) { - if(m_itemCount) - { - QTreeView::paintEvent(event); - } - else - { - paintInfoLabel(event); - } + if(m_itemCount) + { + QTreeView::paintEvent(event); + } + else + { + paintInfoLabel(event); + } } -void VersionListView::paintInfoLabel(QPaintEvent *event) +QString VersionListView::currentEmptyString() const { - QString emptyString; - switch(m_emptyMode) - { - case VersionListView::Empty: - return; - case VersionListView::String: - emptyString = m_emptyString; - break; - case VersionListView::ErrorString: - emptyString = m_emptyErrorString; - break; - } + if(m_itemCount) { + return QString(); + } + switch(m_emptyMode) + { + default: + case VersionListView::Empty: + return QString(); + case VersionListView::String: + return m_emptyString; + case VersionListView::ErrorString: + return m_emptyErrorString; + } +} + + +void VersionListView::paintInfoLabel(QPaintEvent *event) const +{ + QString emptyString = currentEmptyString(); + //calculate the rect for the overlay QPainter painter(viewport()); painter.setRenderHint(QPainter::Antialiasing, true); - QFont font("sans", 20); + QFont font("sans", 20); font.setBold(true); - - QRect bounds = viewport()->geometry(); - bounds.moveTop(0); - QTextLayout layout(emptyString, font); - qreal height = 0.0; - qreal widthUsed = 0.0; - QStringList lines = viewItemTextLayout(layout, bounds.width() - 20, height, widthUsed); - QRect rect (0,0, widthUsed, height); - rect.setWidth(rect.width()+20); - rect.setHeight(rect.height()+20); - rect.moveCenter(bounds.center()); + + QRect bounds = viewport()->geometry(); + bounds.moveTop(0); + auto innerBounds = bounds; + innerBounds.adjust(10, 10, -10, -10); + + QColor background = QApplication::palette().color(QPalette::Foreground); + QColor foreground = QApplication::palette().color(QPalette::Base); + foreground.setAlpha(190); + painter.setFont(font); + auto fontMetrics = painter.fontMetrics(); + auto textRect = fontMetrics.boundingRect(innerBounds, Qt::AlignHCenter | Qt::TextWordWrap, emptyString); + textRect.moveCenter(bounds.center()); + + auto wrapRect = textRect; + wrapRect.adjust(-10, -10, 10, 10); + //check if we are allowed to draw in our area - if (!event->rect().intersects(rect)) { + if (!event->rect().intersects(wrapRect)) { return; } - //draw the letter of the topmost item semitransparent in the middle - QColor background = QApplication::palette().color(QPalette::Foreground); - QColor foreground = QApplication::palette().color(QPalette::Base); - /* - background.setAlpha(128 - scrollFade); - foreground.setAlpha(128 - scrollFade); - */ + painter.setBrush(QBrush(background)); painter.setPen(foreground); - painter.drawRoundedRect(rect, 5.0, 5.0); - foreground.setAlpha(190); + painter.drawRoundedRect(wrapRect, 5.0, 5.0); + painter.setPen(foreground); painter.setFont(font); - painter.drawText(rect, Qt::AlignCenter, lines.join("\n")); - -} - -/* -void ModListView::setModel ( QAbstractItemModel* model ) -{ - QTreeView::setModel ( model ); - auto head = header(); - head->setStretchLastSection(false); - // HACK: this is true for the checkbox column of mod lists - auto string = model->headerData(0,head->orientation()).toString(); - if(!string.size()) - { - head->setSectionResizeMode(0, QHeaderView::ResizeToContents); - head->setSectionResizeMode(1, QHeaderView::Stretch); - for(int i = 2; i < head->count(); i++) - head->setSectionResizeMode(i, QHeaderView::ResizeToContents); - } - else - { - head->setSectionResizeMode(0, QHeaderView::Stretch); - for(int i = 1; i < head->count(); i++) - head->setSectionResizeMode(i, QHeaderView::ResizeToContents); - } + painter.drawText(textRect, Qt::AlignHCenter | Qt::TextWordWrap, emptyString); } -*/ diff --git a/application/widgets/VersionListView.h b/application/widgets/VersionListView.h index b7a881e9..37f7b27e 100644 --- a/application/widgets/VersionListView.h +++ b/application/widgets/VersionListView.h @@ -1,4 +1,4 @@ -/* Copyright 2013-2018 MultiMC Contributors +/* Copyright 2013-2019 MultiMC Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,42 +16,41 @@ #pragma once #include -class Mod; - class VersionListView : public QTreeView { - Q_OBJECT + Q_OBJECT public: - explicit VersionListView(QWidget *parent = 0); - virtual void paintEvent(QPaintEvent *event) override; - virtual void setModel(QAbstractItemModel* model) override; + explicit VersionListView(QWidget *parent = 0); + virtual void paintEvent(QPaintEvent *event) override; + virtual void setModel(QAbstractItemModel* model) override; - enum EmptyMode - { - Empty, - String, - ErrorString - }; + enum EmptyMode + { + Empty, + String, + ErrorString + }; - void setEmptyString(QString emptyString); - void setEmptyErrorString(QString emptyErrorString); - void setEmptyMode(EmptyMode mode); + void setEmptyString(QString emptyString); + void setEmptyErrorString(QString emptyErrorString); + void setEmptyMode(EmptyMode mode); public slots: - virtual void reset() override; + virtual void reset() override; protected slots: - virtual void rowsAboutToBeRemoved(const QModelIndex & parent, int start, int end) override; - virtual void rowsInserted(const QModelIndex &parent, int start, int end) override; + virtual void rowsAboutToBeRemoved(const QModelIndex & parent, int start, int end) override; + virtual void rowsInserted(const QModelIndex &parent, int start, int end) override; private: /* methods */ - void paintInfoLabel(QPaintEvent *event); - void updateEmptyViewPort(); + void paintInfoLabel(QPaintEvent *event) const; + void updateEmptyViewPort(); + QString currentEmptyString() const; private: /* variables */ - int m_itemCount = 0; - QString m_emptyString; - QString m_emptyErrorString; - EmptyMode m_emptyMode = Empty; + int m_itemCount = 0; + QString m_emptyString; + QString m_emptyErrorString; + EmptyMode m_emptyMode = Empty; }; diff --git a/application/widgets/VersionSelectWidget.cpp b/application/widgets/VersionSelectWidget.cpp index ce1141b6..9925a6b4 100644 --- a/application/widgets/VersionSelectWidget.cpp +++ b/application/widgets/VersionSelectWidget.cpp @@ -7,50 +7,51 @@ #include VersionSelectWidget::VersionSelectWidget(QWidget* parent) - : QWidget(parent) + : QWidget(parent) { - setObjectName(QStringLiteral("VersionSelectWidget")); - verticalLayout = new QVBoxLayout(this); - verticalLayout->setObjectName(QStringLiteral("verticalLayout")); - verticalLayout->setContentsMargins(0, 0, 0, 0); + setObjectName(QStringLiteral("VersionSelectWidget")); + verticalLayout = new QVBoxLayout(this); + verticalLayout->setObjectName(QStringLiteral("verticalLayout")); + verticalLayout->setContentsMargins(0, 0, 0, 0); - m_proxyModel = new VersionProxyModel(this); + m_proxyModel = new VersionProxyModel(this); - listView = new VersionListView(this); - listView->setObjectName(QStringLiteral("listView")); - listView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - listView->setAlternatingRowColors(true); - listView->setRootIsDecorated(false); - listView->setItemsExpandable(false); - listView->setWordWrap(true); - listView->header()->setCascadingSectionResizes(true); - listView->header()->setStretchLastSection(false); - listView->setModel(m_proxyModel); - verticalLayout->addWidget(listView); + listView = new VersionListView(this); + listView->setObjectName(QStringLiteral("listView")); + listView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + listView->setAlternatingRowColors(true); + listView->setRootIsDecorated(false); + listView->setItemsExpandable(false); + listView->setWordWrap(true); + listView->header()->setCascadingSectionResizes(true); + listView->header()->setStretchLastSection(false); + listView->setModel(m_proxyModel); + verticalLayout->addWidget(listView); - sneakyProgressBar = new QProgressBar(this); - sneakyProgressBar->setObjectName(QStringLiteral("sneakyProgressBar")); - sneakyProgressBar->setFormat(QStringLiteral("%p%")); - verticalLayout->addWidget(sneakyProgressBar); - sneakyProgressBar->setHidden(true); - connect(listView->selectionModel(), &QItemSelectionModel::currentRowChanged, this, &VersionSelectWidget::currentRowChanged); + sneakyProgressBar = new QProgressBar(this); + sneakyProgressBar->setObjectName(QStringLiteral("sneakyProgressBar")); + sneakyProgressBar->setFormat(QStringLiteral("%p%")); + verticalLayout->addWidget(sneakyProgressBar); + sneakyProgressBar->setHidden(true); + connect(listView->selectionModel(), &QItemSelectionModel::currentRowChanged, this, &VersionSelectWidget::currentRowChanged); - QMetaObject::connectSlotsByName(this); + QMetaObject::connectSlotsByName(this); } void VersionSelectWidget::setCurrentVersion(const QString& version) { - m_currentVersion = version; + m_currentVersion = version; + m_proxyModel->setCurrentVersion(version); } void VersionSelectWidget::setEmptyString(QString emptyString) { - listView->setEmptyString(emptyString); + listView->setEmptyString(emptyString); } void VersionSelectWidget::setEmptyErrorString(QString emptyErrorString) { - listView->setEmptyErrorString(emptyErrorString); + listView->setEmptyErrorString(emptyErrorString); } VersionSelectWidget::~VersionSelectWidget() @@ -59,143 +60,143 @@ VersionSelectWidget::~VersionSelectWidget() void VersionSelectWidget::setResizeOn(int column) { - listView->header()->setSectionResizeMode(resizeOnColumn, QHeaderView::ResizeToContents); - resizeOnColumn = column; - listView->header()->setSectionResizeMode(resizeOnColumn, QHeaderView::Stretch); + listView->header()->setSectionResizeMode(resizeOnColumn, QHeaderView::ResizeToContents); + resizeOnColumn = column; + listView->header()->setSectionResizeMode(resizeOnColumn, QHeaderView::Stretch); } void VersionSelectWidget::initialize(BaseVersionList *vlist) { - m_vlist = vlist; - m_proxyModel->setSourceModel(vlist); - listView->header()->setSectionResizeMode(QHeaderView::ResizeToContents); - listView->header()->setSectionResizeMode(resizeOnColumn, QHeaderView::Stretch); - - if (!m_vlist->isLoaded()) - { - loadList(); - } - else - { - if (m_proxyModel->rowCount() == 0) - { - listView->setEmptyMode(VersionListView::String); - } - preselect(); - } + m_vlist = vlist; + m_proxyModel->setSourceModel(vlist); + listView->header()->setSectionResizeMode(QHeaderView::ResizeToContents); + listView->header()->setSectionResizeMode(resizeOnColumn, QHeaderView::Stretch); + + if (!m_vlist->isLoaded()) + { + loadList(); + } + else + { + if (m_proxyModel->rowCount() == 0) + { + listView->setEmptyMode(VersionListView::String); + } + preselect(); + } } void VersionSelectWidget::closeEvent(QCloseEvent * event) { - QWidget::closeEvent(event); + QWidget::closeEvent(event); } void VersionSelectWidget::loadList() { - auto newTask = m_vlist->getLoadTask(); - if (!newTask) - { - return; - } - loadTask = newTask.get(); - connect(loadTask, &Task::succeeded, this, &VersionSelectWidget::onTaskSucceeded); - connect(loadTask, &Task::failed, this, &VersionSelectWidget::onTaskFailed); - connect(loadTask, &Task::progress, this, &VersionSelectWidget::changeProgress); - if(!loadTask->isRunning()) - { - loadTask->start(); - } - sneakyProgressBar->setHidden(false); + auto newTask = m_vlist->getLoadTask(); + if (!newTask) + { + return; + } + loadTask = newTask.get(); + connect(loadTask, &Task::succeeded, this, &VersionSelectWidget::onTaskSucceeded); + connect(loadTask, &Task::failed, this, &VersionSelectWidget::onTaskFailed); + connect(loadTask, &Task::progress, this, &VersionSelectWidget::changeProgress); + if(!loadTask->isRunning()) + { + loadTask->start(); + } + sneakyProgressBar->setHidden(false); } void VersionSelectWidget::onTaskSucceeded() { - if (m_proxyModel->rowCount() == 0) - { - listView->setEmptyMode(VersionListView::String); - } - sneakyProgressBar->setHidden(true); - preselect(); - loadTask = nullptr; + if (m_proxyModel->rowCount() == 0) + { + listView->setEmptyMode(VersionListView::String); + } + sneakyProgressBar->setHidden(true); + preselect(); + loadTask = nullptr; } void VersionSelectWidget::onTaskFailed(const QString& reason) { - CustomMessageBox::selectable(this, tr("Error"), tr("List update failed:\n%1").arg(reason), QMessageBox::Warning)->show(); - onTaskSucceeded(); + CustomMessageBox::selectable(this, tr("Error"), tr("List update failed:\n%1").arg(reason), QMessageBox::Warning)->show(); + onTaskSucceeded(); } void VersionSelectWidget::changeProgress(qint64 current, qint64 total) { - sneakyProgressBar->setMaximum(total); - sneakyProgressBar->setValue(current); + sneakyProgressBar->setMaximum(total); + sneakyProgressBar->setValue(current); } void VersionSelectWidget::currentRowChanged(const QModelIndex& current, const QModelIndex&) { - auto variant = m_proxyModel->data(current, BaseVersionList::VersionPointerRole); - emit selectedVersionChanged(variant.value()); + auto variant = m_proxyModel->data(current, BaseVersionList::VersionPointerRole); + emit selectedVersionChanged(variant.value()); } void VersionSelectWidget::preselect() { - if(preselectedAlready) - return; - selectCurrent(); - if(preselectedAlready) - return; - selectRecommended(); + if(preselectedAlready) + return; + selectCurrent(); + if(preselectedAlready) + return; + selectRecommended(); } void VersionSelectWidget::selectCurrent() { - if(m_currentVersion.isEmpty()) - { - return; - } - auto idx = m_proxyModel->getVersion(m_currentVersion); - if(idx.isValid()) - { - preselectedAlready = true; - listView->selectionModel()->setCurrentIndex(idx,QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows); - listView->scrollTo(idx, QAbstractItemView::PositionAtCenter); - } + if(m_currentVersion.isEmpty()) + { + return; + } + auto idx = m_proxyModel->getVersion(m_currentVersion); + if(idx.isValid()) + { + preselectedAlready = true; + listView->selectionModel()->setCurrentIndex(idx,QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows); + listView->scrollTo(idx, QAbstractItemView::PositionAtCenter); + } } void VersionSelectWidget::selectRecommended() { - auto idx = m_proxyModel->getRecommended(); - if(idx.isValid()) - { - preselectedAlready = true; - listView->selectionModel()->setCurrentIndex(idx,QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows); - listView->scrollTo(idx, QAbstractItemView::PositionAtCenter); - } + auto idx = m_proxyModel->getRecommended(); + if(idx.isValid()) + { + preselectedAlready = true; + listView->selectionModel()->setCurrentIndex(idx,QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows); + listView->scrollTo(idx, QAbstractItemView::PositionAtCenter); + } } bool VersionSelectWidget::hasVersions() const { - return m_proxyModel->rowCount(QModelIndex()) != 0; + return m_proxyModel->rowCount(QModelIndex()) != 0; } BaseVersionPtr VersionSelectWidget::selectedVersion() const { - auto currentIndex = listView->selectionModel()->currentIndex(); - auto variant = m_proxyModel->data(currentIndex, BaseVersionList::VersionPointerRole); - return variant.value(); + auto currentIndex = listView->selectionModel()->currentIndex(); + auto variant = m_proxyModel->data(currentIndex, BaseVersionList::VersionPointerRole); + return variant.value(); } void VersionSelectWidget::setExactFilter(BaseVersionList::ModelRoles role, QString filter) { - m_proxyModel->setFilter(role, new ExactFilter(filter)); + m_proxyModel->setFilter(role, new ExactFilter(filter)); } void VersionSelectWidget::setFuzzyFilter(BaseVersionList::ModelRoles role, QString filter) { - m_proxyModel->setFilter(role, new ContainsFilter(filter)); + m_proxyModel->setFilter(role, new ContainsFilter(filter)); } void VersionSelectWidget::setFilter(BaseVersionList::ModelRoles role, Filter *filter) { - m_proxyModel->setFilter(role, filter); + m_proxyModel->setFilter(role, filter); } diff --git a/application/widgets/VersionSelectWidget.h b/application/widgets/VersionSelectWidget.h index c134887f..701f568e 100644 --- a/application/widgets/VersionSelectWidget.h +++ b/application/widgets/VersionSelectWidget.h @@ -1,4 +1,4 @@ -/* Copyright 2013-2018 MultiMC Contributors +/* Copyright 2013-2019 MultiMC Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,55 +27,55 @@ class Filter; class VersionSelectWidget: public QWidget { - Q_OBJECT + Q_OBJECT public: - explicit VersionSelectWidget(QWidget *parent = 0); - ~VersionSelectWidget(); + explicit VersionSelectWidget(QWidget *parent = 0); + ~VersionSelectWidget(); - //! loads the list if needed. - void initialize(BaseVersionList *vlist); + //! loads the list if needed. + void initialize(BaseVersionList *vlist); - //! Starts a task that loads the list. - void loadList(); + //! Starts a task that loads the list. + void loadList(); - bool hasVersions() const; - BaseVersionPtr selectedVersion() const; - void selectRecommended(); - void selectCurrent(); + bool hasVersions() const; + BaseVersionPtr selectedVersion() const; + void selectRecommended(); + void selectCurrent(); - void setCurrentVersion(const QString & version); - void setFuzzyFilter(BaseVersionList::ModelRoles role, QString filter); - void setExactFilter(BaseVersionList::ModelRoles role, QString filter); - void setFilter(BaseVersionList::ModelRoles role, Filter *filter); - void setEmptyString(QString emptyString); - void setEmptyErrorString(QString emptyErrorString); - void setResizeOn(int column); + void setCurrentVersion(const QString & version); + void setFuzzyFilter(BaseVersionList::ModelRoles role, QString filter); + void setExactFilter(BaseVersionList::ModelRoles role, QString filter); + void setFilter(BaseVersionList::ModelRoles role, Filter *filter); + void setEmptyString(QString emptyString); + void setEmptyErrorString(QString emptyErrorString); + void setResizeOn(int column); signals: - void selectedVersionChanged(BaseVersionPtr version); + void selectedVersionChanged(BaseVersionPtr version); protected: - virtual void closeEvent ( QCloseEvent* ); + virtual void closeEvent ( QCloseEvent* ); private slots: - void onTaskSucceeded(); - void onTaskFailed(const QString &reason); - void changeProgress(qint64 current, qint64 total); - void currentRowChanged(const QModelIndex ¤t, const QModelIndex &); + void onTaskSucceeded(); + void onTaskFailed(const QString &reason); + void changeProgress(qint64 current, qint64 total); + void currentRowChanged(const QModelIndex ¤t, const QModelIndex &); private: - void preselect(); + void preselect(); private: - QString m_currentVersion; - BaseVersionList *m_vlist = nullptr; - VersionProxyModel *m_proxyModel = nullptr; - int resizeOnColumn = 0; - Task * loadTask; - bool preselectedAlready = false; + QString m_currentVersion; + BaseVersionList *m_vlist = nullptr; + VersionProxyModel *m_proxyModel = nullptr; + int resizeOnColumn = 0; + Task * loadTask; + bool preselectedAlready = false; private: - QVBoxLayout *verticalLayout = nullptr; - VersionListView *listView = nullptr; - QProgressBar *sneakyProgressBar = nullptr; + QVBoxLayout *verticalLayout = nullptr; + VersionListView *listView = nullptr; + QProgressBar *sneakyProgressBar = nullptr; }; diff --git a/application/widgets/WideBar.cpp b/application/widgets/WideBar.cpp new file mode 100644 index 00000000..cbd6c617 --- /dev/null +++ b/application/widgets/WideBar.cpp @@ -0,0 +1,116 @@ +#include "WideBar.h" +#include +#include + +class ActionButton : public QToolButton +{ + Q_OBJECT +public: + ActionButton(QAction * action, QWidget * parent = 0) : QToolButton(parent), m_action(action) { + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + connect(action, &QAction::changed, this, &ActionButton::actionChanged); + connect(this, &ActionButton::clicked, action, &QAction::trigger); + actionChanged(); + }; +private slots: + void actionChanged() { + setEnabled(m_action->isEnabled()); + setChecked(m_action->isChecked()); + setCheckable(m_action->isCheckable()); + setText(m_action->text()); + setIcon(m_action->icon()); + setToolTip(m_action->toolTip()); + setHidden(!m_action->isVisible()); + setFocusPolicy(Qt::NoFocus); + } +private: + QAction * m_action; +}; + + +WideBar::WideBar(const QString& title, QWidget* parent) : QToolBar(title, parent) +{ + setFloatable(false); + setMovable(false); +} + +WideBar::WideBar(QWidget* parent) : QToolBar(parent) +{ + setFloatable(false); + setMovable(false); +} + +struct WideBar::BarEntry { + enum Type { + None, + Action, + Separator, + Spacer + } type = None; + QAction *qAction = nullptr; + QAction *wideAction = nullptr; +}; + + +WideBar::~WideBar() +{ + for(auto *iter: m_entries) { + delete iter; + } +} + +void WideBar::addAction(QAction* action) +{ + auto entry = new BarEntry(); + entry->qAction = addWidget(new ActionButton(action, this)); + entry->wideAction = action; + entry->type = BarEntry::Action; + m_entries.push_back(entry); +} + +void WideBar::addSeparator() +{ + auto entry = new BarEntry(); + entry->qAction = QToolBar::addSeparator(); + entry->type = BarEntry::Separator; + m_entries.push_back(entry); +} + +void WideBar::insertSpacer(QAction* action) +{ + auto iter = std::find_if(m_entries.begin(), m_entries.end(), [action](BarEntry * entry) { + return entry->wideAction == action; + }); + if(iter == m_entries.end()) { + return; + } + QWidget* spacer = new QWidget(); + spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + + auto entry = new BarEntry(); + entry->qAction = insertWidget((*iter)->qAction, spacer); + entry->type = BarEntry::Spacer; + m_entries.insert(iter, entry); +} + +QMenu * WideBar::createContextMenu(QWidget *parent, const QString & title) +{ + QMenu *contextMenu = new QMenu(title, parent); + for(auto & item: m_entries) { + switch(item->type) { + default: + case BarEntry::None: + break; + case BarEntry::Separator: + case BarEntry::Spacer: + contextMenu->addSeparator(); + break; + case BarEntry::Action: + contextMenu->addAction(item->wideAction); + break; + } + } + return contextMenu; +} + +#include "WideBar.moc" diff --git a/application/widgets/WideBar.h b/application/widgets/WideBar.h new file mode 100644 index 00000000..d1b8cbe7 --- /dev/null +++ b/application/widgets/WideBar.h @@ -0,0 +1,26 @@ +#pragma once + +#include +#include +#include + +class QMenu; + +class WideBar : public QToolBar +{ + Q_OBJECT + +public: + explicit WideBar(const QString &title, QWidget * parent = nullptr); + explicit WideBar(QWidget * parent = nullptr); + virtual ~WideBar(); + + void addAction(QAction *action); + void addSeparator(); + void insertSpacer(QAction *action); + QMenu *createContextMenu(QWidget *parent = nullptr, const QString & title = QString()); + +private: + struct BarEntry; + QList m_entries; +}; -- cgit v1.2.3