Merge remote-tracking branch 'upstream/develop' into resource-meta
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
This commit is contained in:
@@ -47,11 +47,18 @@ ExportPackDialog::ExportPackDialog(InstancePtr instance, QWidget* parent, ModPla
|
||||
|
||||
if (m_provider == ModPlatform::ResourceProvider::MODRINTH) {
|
||||
setWindowTitle(tr("Export Modrinth Pack"));
|
||||
ui->summary->setText(instance->settings()->get("ExportSummary").toString());
|
||||
|
||||
ui->authorLabel->hide();
|
||||
ui->author->hide();
|
||||
|
||||
ui->summary->setPlainText(instance->settings()->get("ExportSummary").toString());
|
||||
} else {
|
||||
setWindowTitle(tr("Export CurseForge Pack"));
|
||||
ui->summaryLabel->setText(tr("&Author"));
|
||||
ui->summary->setText(instance->settings()->get("ExportAuthor").toString());
|
||||
|
||||
ui->summaryLabel->hide();
|
||||
ui->summary->hide();
|
||||
|
||||
ui->author->setText(instance->settings()->get("ExportAuthor").toString());
|
||||
}
|
||||
|
||||
// ensure a valid pack is generated
|
||||
@@ -108,9 +115,13 @@ void ExportPackDialog::done(int result)
|
||||
auto settings = instance->settings();
|
||||
settings->set("ExportName", ui->name->text());
|
||||
settings->set("ExportVersion", ui->version->text());
|
||||
settings->set(m_provider == ModPlatform::ResourceProvider::FLAME ? "ExportAuthor" : "ExportSummary", ui->summary->text());
|
||||
settings->set("ExportOptionalFiles", ui->optionalFiles->isChecked());
|
||||
|
||||
if (m_provider == ModPlatform::ResourceProvider::MODRINTH)
|
||||
settings->set("ExportSummary", ui->summary->toPlainText());
|
||||
else
|
||||
settings->set("ExportAuthor", ui->author->text());
|
||||
|
||||
if (result == Accepted) {
|
||||
const QString name = ui->name->text().isEmpty() ? instance->name() : ui->name->text();
|
||||
const QString filename = FS::RemoveInvalidFilenameChars(name);
|
||||
@@ -134,10 +145,10 @@ void ExportPackDialog::done(int result)
|
||||
|
||||
Task* task;
|
||||
if (m_provider == ModPlatform::ResourceProvider::MODRINTH) {
|
||||
task = new ModrinthPackExportTask(name, ui->version->text(), ui->summary->text(), ui->optionalFiles->isChecked(), instance,
|
||||
output, std::bind(&FileIgnoreProxy::filterFile, proxy, std::placeholders::_1));
|
||||
task = new ModrinthPackExportTask(name, ui->version->text(), ui->summary->toPlainText(), ui->optionalFiles->isChecked(),
|
||||
instance, output, std::bind(&FileIgnoreProxy::filterFile, proxy, std::placeholders::_1));
|
||||
} else {
|
||||
task = new FlamePackExportTask(name, ui->version->text(), ui->summary->text(), ui->optionalFiles->isChecked(), instance, output,
|
||||
task = new FlamePackExportTask(name, ui->version->text(), ui->author->text(), ui->optionalFiles->isChecked(), instance, output,
|
||||
std::bind(&FileIgnoreProxy::filterFile, proxy, std::placeholders::_1));
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>650</width>
|
||||
<height>510</height>
|
||||
<height>532</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizeGripEnabled">
|
||||
@@ -19,21 +19,8 @@
|
||||
<property name="title">
|
||||
<string>&Description</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="summaryLabel">
|
||||
<property name="text">
|
||||
<string>&Summary</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>summary</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLineEdit" name="summary"/>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QLabel" name="nameLabel">
|
||||
<property name="text">
|
||||
<string>&Name</string>
|
||||
@@ -43,7 +30,10 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="name"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="versionLabel">
|
||||
<property name="text">
|
||||
<string>&Version</string>
|
||||
@@ -53,16 +43,43 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="name"/>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="version">
|
||||
<property name="text">
|
||||
<string>1.0.0</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="summaryLabel">
|
||||
<property name="text">
|
||||
<string>&Summary</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>summary</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPlainTextEdit" name="summary">
|
||||
<property name="tabChangesFocus">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="authorLabel">
|
||||
<property name="text">
|
||||
<string>&Author</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>author</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="author"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -124,6 +141,7 @@
|
||||
<tabstop>name</tabstop>
|
||||
<tabstop>version</tabstop>
|
||||
<tabstop>summary</tabstop>
|
||||
<tabstop>author</tabstop>
|
||||
<tabstop>files</tabstop>
|
||||
<tabstop>optionalFiles</tabstop>
|
||||
</tabstops>
|
||||
|
||||
@@ -97,6 +97,9 @@ NewInstanceDialog::NewInstanceDialog(const QString& initialGroup,
|
||||
ui->verticalLayout->insertWidget(2, m_container);
|
||||
|
||||
m_container->addButtons(m_buttons);
|
||||
connect(m_container, &PageContainer::selectedPageChanged, this, [this](BasePage* previous, BasePage* selected) {
|
||||
m_buttons->button(QDialogButtonBox::Ok)->setEnabled(creationTask && !instName().isEmpty());
|
||||
});
|
||||
|
||||
// Bonk Qt over its stupid head and make sure it understands which button is the default one...
|
||||
// See: https://stackoverflow.com/questions/24556831/qbuttonbox-set-default-button
|
||||
|
||||
@@ -130,7 +130,7 @@ void ResourceDownloadDialog::confirm()
|
||||
auto confirm_dialog = ReviewMessageBox::create(this, tr("Confirm %1 to download").arg(resourcesString()));
|
||||
confirm_dialog->retranslateUi(resourcesString());
|
||||
|
||||
QHash<QString, QStringList> getRequiredBy;
|
||||
QHash<QString, GetModDependenciesTask::PackDependencyExtraInfo> dependencyExtraInfo;
|
||||
if (auto task = getModDependenciesTask(); task) {
|
||||
connect(task.get(), &Task::failed, this,
|
||||
[&](QString reason) { CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->exec(); });
|
||||
@@ -155,7 +155,7 @@ void ResourceDownloadDialog::confirm()
|
||||
} else {
|
||||
for (auto dep : task->getDependecies())
|
||||
addResource(dep->pack, dep->version);
|
||||
getRequiredBy = task->getRequiredBy();
|
||||
dependencyExtraInfo = task->getExtraInfo();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,9 +164,10 @@ void ResourceDownloadDialog::confirm()
|
||||
return QString::compare(a->getName(), b->getName(), Qt::CaseInsensitive) < 0;
|
||||
});
|
||||
for (auto& task : selected) {
|
||||
auto extraInfo = dependencyExtraInfo.value(task->getPack()->addonId.toString());
|
||||
confirm_dialog->appendResource({ task->getName(), task->getFilename(), task->getCustomPath(),
|
||||
ModPlatform::ProviderCapabilities::name(task->getProvider()), getRequiredBy.value(task->getPack()->addonId.toString()),
|
||||
task->getVersion().version_type.toString() });
|
||||
ModPlatform::ProviderCapabilities::name(task->getProvider()), extraInfo.required_by,
|
||||
task->getVersion().version_type.toString(), !extraInfo.maybe_installed });
|
||||
}
|
||||
|
||||
if (confirm_dialog->exec()) {
|
||||
|
||||
@@ -219,19 +219,20 @@ void ResourceUpdateDialog::checkCandidates()
|
||||
}
|
||||
static FlameAPI api;
|
||||
|
||||
auto getRequiredBy = depTask->getRequiredBy();
|
||||
auto dependencyExtraInfo = depTask->getExtraInfo();
|
||||
|
||||
for (const auto& dep : depTask->getDependecies()) {
|
||||
auto changelog = dep->version.changelog;
|
||||
if (dep->pack->provider == ModPlatform::ResourceProvider::FLAME)
|
||||
changelog = api.getModFileChangelog(dep->version.addonId.toInt(), dep->version.fileId.toInt());
|
||||
auto download_task = makeShared<ResourceDownloadTask>(dep->pack, dep->version, m_resource_model);
|
||||
CheckUpdateTask::Update updatable = { dep->pack->name, dep->version.hash,
|
||||
tr("Not installed"), dep->version.version,
|
||||
dep->version.version_type, changelog,
|
||||
dep->pack->provider, download_task };
|
||||
auto extraInfo = dependencyExtraInfo.value(dep->version.addonId.toString());
|
||||
CheckUpdateTask::Update updatable = {
|
||||
dep->pack->name, dep->version.hash, tr("Not installed"), dep->version.version, dep->version.version_type,
|
||||
changelog, dep->pack->provider, download_task, !extraInfo.maybe_installed
|
||||
};
|
||||
|
||||
appendResource(updatable, getRequiredBy.value(dep->version.addonId.toString()));
|
||||
appendResource(updatable, extraInfo.required_by);
|
||||
m_tasks.insert(updatable.name, updatable.download);
|
||||
}
|
||||
}
|
||||
@@ -418,7 +419,10 @@ void ResourceUpdateDialog::onMetadataFailed(Resource* resource, bool try_others,
|
||||
void ResourceUpdateDialog::appendResource(CheckUpdateTask::Update const& info, QStringList requiredBy)
|
||||
{
|
||||
auto item_top = new QTreeWidgetItem(ui->modTreeWidget);
|
||||
item_top->setCheckState(0, Qt::CheckState::Checked);
|
||||
item_top->setCheckState(0, info.enabled ? Qt::CheckState::Checked : Qt::CheckState::Unchecked);
|
||||
if (!info.enabled) {
|
||||
item_top->setToolTip(0, tr("Mod was disabled as it may be already instaled."));
|
||||
}
|
||||
item_top->setText(0, info.name);
|
||||
item_top->setExpanded(true);
|
||||
|
||||
|
||||
@@ -35,8 +35,11 @@ auto ReviewMessageBox::create(QWidget* parent, QString&& title, QString&& icon)
|
||||
void ReviewMessageBox::appendResource(ResourceInformation&& info)
|
||||
{
|
||||
auto itemTop = new QTreeWidgetItem(ui->modTreeWidget);
|
||||
itemTop->setCheckState(0, Qt::CheckState::Checked);
|
||||
itemTop->setCheckState(0, info.enabled ? Qt::CheckState::Checked : Qt::CheckState::Unchecked);
|
||||
itemTop->setText(0, info.name);
|
||||
if (!info.enabled) {
|
||||
itemTop->setToolTip(0, tr("Mod was disabled as it may be already instaled."));
|
||||
}
|
||||
|
||||
auto filenameItem = new QTreeWidgetItem(itemTop);
|
||||
filenameItem->setText(0, tr("Filename: %1").arg(info.filename));
|
||||
|
||||
@@ -20,6 +20,7 @@ class ReviewMessageBox : public QDialog {
|
||||
QString provider;
|
||||
QStringList required_by;
|
||||
QString version_type;
|
||||
bool enabled = true;
|
||||
};
|
||||
|
||||
void appendResource(ResourceInformation&& info);
|
||||
|
||||
@@ -465,7 +465,7 @@ void InstanceView::paintEvent([[maybe_unused]] QPaintEvent* event)
|
||||
widWidth = m_catPixmap.width();
|
||||
if (m_catPixmap.height() < widHeight)
|
||||
widHeight = m_catPixmap.height();
|
||||
auto pixmap = m_catPixmap.scaled(widWidth, widHeight, Qt::KeepAspectRatio);
|
||||
auto pixmap = m_catPixmap.scaled(widWidth, widHeight, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||
QRect rectOfPixmap = pixmap.rect();
|
||||
rectOfPixmap.moveBottomRight(this->viewport()->rect().bottomRight());
|
||||
painter.drawPixmap(rectOfPixmap.topLeft(), pixmap);
|
||||
@@ -482,32 +482,42 @@ void InstanceView::paintEvent([[maybe_unused]] QPaintEvent* event)
|
||||
|
||||
if (model()->rowCount() == 0) {
|
||||
painter.save();
|
||||
const QString line1 = tr("Welcome!");
|
||||
const QString line2 = tr("Click \"Add Instance\" to get started.");
|
||||
auto rect = this->viewport()->rect();
|
||||
auto font = option.font;
|
||||
font.setPointSize(37);
|
||||
painter.setFont(font);
|
||||
auto fm = painter.fontMetrics();
|
||||
QString emptyString = tr("Welcome!") + "\n" + tr("Click \"Add Instance\" to get started.");
|
||||
|
||||
if (rect.height() <= (fm.height() * 5) || rect.width() <= fm.horizontalAdvance(line2)) {
|
||||
auto s = rect.height() / (5. * fm.height());
|
||||
auto sx = rect.width() * 1. / fm.horizontalAdvance(line2);
|
||||
if (s >= sx)
|
||||
s = sx;
|
||||
auto ps = font.pointSize() * s;
|
||||
if (ps <= 0)
|
||||
ps = 1;
|
||||
font.setPointSize(ps);
|
||||
painter.setFont(font);
|
||||
fm = painter.fontMetrics();
|
||||
// calculate the rect for the overlay
|
||||
painter.setRenderHint(QPainter::Antialiasing, true);
|
||||
QFont font("sans", 20);
|
||||
font.setBold(true);
|
||||
|
||||
QRect bounds = viewport()->geometry();
|
||||
bounds.moveTop(0);
|
||||
auto innerBounds = bounds;
|
||||
innerBounds.adjust(10, 10, -10, -10);
|
||||
|
||||
QColor background = QApplication::palette().color(QPalette::WindowText);
|
||||
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(wrapRect)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// text
|
||||
rect.setTop(rect.top() + fm.height() * 1.5);
|
||||
painter.drawText(rect, Qt::AlignHCenter, line1);
|
||||
rect.setTop(rect.top() + fm.height());
|
||||
painter.drawText(rect, Qt::AlignHCenter, line2);
|
||||
painter.setBrush(QBrush(background));
|
||||
painter.setPen(foreground);
|
||||
painter.drawRoundedRect(wrapRect, 5.0, 5.0);
|
||||
|
||||
painter.setPen(foreground);
|
||||
painter.setFont(font);
|
||||
painter.drawText(textRect, Qt::AlignHCenter | Qt::TextWordWrap, emptyString);
|
||||
|
||||
painter.restore();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -109,6 +109,7 @@ void MinecraftPage::applySettings()
|
||||
s->set("EnableFeralGamemode", ui->enableFeralGamemodeCheck->isChecked());
|
||||
s->set("EnableMangoHud", ui->enableMangoHud->isChecked());
|
||||
s->set("UseDiscreteGpu", ui->useDiscreteGpuCheck->isChecked());
|
||||
s->set("UseZink", ui->useZink->isChecked());
|
||||
|
||||
// Game time
|
||||
s->set("ShowGameTime", ui->showGameTime->isChecked());
|
||||
@@ -151,6 +152,7 @@ void MinecraftPage::loadSettings()
|
||||
ui->enableFeralGamemodeCheck->setChecked(s->get("EnableFeralGamemode").toBool());
|
||||
ui->enableMangoHud->setChecked(s->get("EnableMangoHud").toBool());
|
||||
ui->useDiscreteGpuCheck->setChecked(s->get("UseDiscreteGpu").toBool());
|
||||
ui->useZink->setChecked(s->get("UseZink").toBool());
|
||||
|
||||
#if !defined(Q_OS_LINUX)
|
||||
ui->perfomanceGroupBox->setVisible(false);
|
||||
|
||||
@@ -309,6 +309,16 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="useZink">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Use Zink, a Mesa OpenGL driver that implements OpenGL on top of Vulkan. Performance may vary depending on the situation. Note: If no suitable Vulkan driver is found, software rendering will be used.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Use Zink</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
||||
@@ -232,10 +232,13 @@ void InstanceSettingsPage::applySettings()
|
||||
m_settings->set("EnableFeralGamemode", ui->enableFeralGamemodeCheck->isChecked());
|
||||
m_settings->set("EnableMangoHud", ui->enableMangoHud->isChecked());
|
||||
m_settings->set("UseDiscreteGpu", ui->useDiscreteGpuCheck->isChecked());
|
||||
m_settings->set("UseZink", ui->useZink->isChecked());
|
||||
|
||||
} else {
|
||||
m_settings->reset("EnableFeralGamemode");
|
||||
m_settings->reset("EnableMangoHud");
|
||||
m_settings->reset("UseDiscreteGpu");
|
||||
m_settings->reset("UseZink");
|
||||
}
|
||||
|
||||
// Game time
|
||||
@@ -354,6 +357,7 @@ void InstanceSettingsPage::loadSettings()
|
||||
ui->enableFeralGamemodeCheck->setChecked(m_settings->get("EnableFeralGamemode").toBool());
|
||||
ui->enableMangoHud->setChecked(m_settings->get("EnableMangoHud").toBool());
|
||||
ui->useDiscreteGpuCheck->setChecked(m_settings->get("UseDiscreteGpu").toBool());
|
||||
ui->useZink->setChecked(m_settings->get("UseZink").toBool());
|
||||
|
||||
#if !defined(Q_OS_LINUX)
|
||||
ui->settingsTabs->setTabVisible(ui->settingsTabs->indexOf(ui->performancePage), false);
|
||||
|
||||
@@ -567,6 +567,16 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="useZink">
|
||||
<property name="toolTip">
|
||||
<string>Use Zink, a Mesa OpenGL driver that implements OpenGL on top of Vulkan. Performance may vary depending on the situation. Note: If no suitable Vulkan driver is found, software rendering will be used.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Use Zink</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
||||
@@ -123,6 +123,10 @@ void ImportPage::updateState()
|
||||
// need to find the download link for the modpack
|
||||
// format of url curseforge://install?addonId=IDHERE&fileId=IDHERE
|
||||
QUrlQuery query(url);
|
||||
if (query.allQueryItemValues("addonId").isEmpty() || query.allQueryItemValues("fileId").isEmpty()) {
|
||||
qDebug() << "Invalid curseforge link:" << url;
|
||||
return;
|
||||
}
|
||||
auto addonId = query.allQueryItemValues("addonId")[0];
|
||||
auto fileId = query.allQueryItemValues("fileId")[0];
|
||||
auto array = std::make_shared<QByteArray>();
|
||||
@@ -200,7 +204,9 @@ void ImportPage::setExtraInfo(const QMap<QString, QString>& extra_info)
|
||||
|
||||
void ImportPage::on_modpackBtn_clicked()
|
||||
{
|
||||
auto filter = QMimeDatabase().mimeTypeForName("application/zip").filterString();
|
||||
const QMimeType zip = QMimeDatabase().mimeTypeForName("application/zip");
|
||||
auto filter = tr("Supported files") + QString(" (%1 *.mrpack)").arg(zip.globPatterns().join(" "));
|
||||
filter += ";;" + zip.filterString();
|
||||
//: Option for filtering for *.mrpack files when importing
|
||||
filter += ";;" + tr("Modrinth pack") + " (*.mrpack)";
|
||||
const QUrl url = QFileDialog::getOpenFileUrl(this, tr("Choose modpack"), modpackUrl(), filter);
|
||||
|
||||
@@ -90,6 +90,7 @@ void ModPage::filterMods()
|
||||
void ModPage::triggerSearch()
|
||||
{
|
||||
m_filter = m_filter_widget->getFilter();
|
||||
m_ui->packView->selectionModel()->setCurrentIndex({}, QItemSelectionModel::SelectionFlag::ClearAndSelect);
|
||||
m_ui->packView->clearSelection();
|
||||
m_ui->packDescription->clear();
|
||||
m_ui->versionSelectionBox->clear();
|
||||
|
||||
@@ -209,7 +209,8 @@ void ResourceModel::loadEntry(QModelIndex& entry)
|
||||
};
|
||||
if (!callbacks.on_fail)
|
||||
callbacks.on_fail = [](QString reason, int) {
|
||||
QMessageBox::critical(nullptr, tr("Error"), tr("A network error occurred. Could not load project versions:%1").arg(reason));
|
||||
QMessageBox::critical(nullptr, tr("Error"),
|
||||
tr("A network error occurred. Could not load project versions: %1").arg(reason));
|
||||
};
|
||||
|
||||
if (auto job = m_api->getProjectVersions(std::move(args), std::move(callbacks)); job)
|
||||
@@ -232,7 +233,7 @@ void ResourceModel::loadEntry(QModelIndex& entry)
|
||||
callbacks.on_fail = [this](QString reason) {
|
||||
if (!s_running_models.constFind(this).value())
|
||||
return;
|
||||
QMessageBox::critical(nullptr, tr("Error"), tr("A network error occurred. Could not load project info:%1").arg(reason));
|
||||
QMessageBox::critical(nullptr, tr("Error"), tr("A network error occurred. Could not load project info: %1").arg(reason));
|
||||
};
|
||||
if (!callbacks.on_abort)
|
||||
callbacks.on_abort = [this] {
|
||||
|
||||
@@ -23,6 +23,7 @@ ResourcePackResourcePage::ResourcePackResourcePage(ResourceDownloadDialog* dialo
|
||||
|
||||
void ResourcePackResourcePage::triggerSearch()
|
||||
{
|
||||
m_ui->packView->selectionModel()->setCurrentIndex({}, QItemSelectionModel::SelectionFlag::ClearAndSelect);
|
||||
m_ui->packView->clearSelection();
|
||||
m_ui->packDescription->clear();
|
||||
m_ui->versionSelectionBox->clear();
|
||||
|
||||
@@ -25,6 +25,7 @@ ShaderPackResourcePage::ShaderPackResourcePage(ShaderPackDownloadDialog* dialog,
|
||||
|
||||
void ShaderPackResourcePage::triggerSearch()
|
||||
{
|
||||
m_ui->packView->selectionModel()->setCurrentIndex({}, QItemSelectionModel::SelectionFlag::ClearAndSelect);
|
||||
m_ui->packView->clearSelection();
|
||||
m_ui->packDescription->clear();
|
||||
m_ui->versionSelectionBox->clear();
|
||||
|
||||
@@ -104,6 +104,7 @@ void ModrinthPage::retranslate()
|
||||
void ModrinthPage::openedImpl()
|
||||
{
|
||||
BasePage::openedImpl();
|
||||
suggestCurrent();
|
||||
triggerSearch();
|
||||
}
|
||||
|
||||
|
||||
@@ -11,43 +11,7 @@
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="font">
|
||||
<font>
|
||||
<italic>true</italic>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Note: Modrinth modpacks are still in alpha phase. Some things may be rough on the edges, or not working at all! Use it with caution.</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<layout class="QHBoxLayout">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="searchEdit">
|
||||
<property name="placeholderText">
|
||||
<string>Search and filter ...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="searchButton">
|
||||
<property name="text">
|
||||
<string>Search</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<item row="2" column="0">
|
||||
<layout class="QHBoxLayout">
|
||||
<item>
|
||||
<widget class="QListView" name="packView">
|
||||
@@ -77,7 +41,7 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<item row="3" column="0">
|
||||
<layout class="QHBoxLayout">
|
||||
<item>
|
||||
<widget class="QComboBox" name="sortByBox"/>
|
||||
@@ -97,6 +61,24 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<layout class="QHBoxLayout">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="searchEdit">
|
||||
<property name="placeholderText">
|
||||
<string>Search and filter ...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="searchButton">
|
||||
<property name="text">
|
||||
<string>Search</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
|
||||
@@ -36,7 +36,10 @@
|
||||
#include "ui/themes/CatPack.h"
|
||||
#include <QDate>
|
||||
#include <QDir>
|
||||
#include <QDirIterator>
|
||||
#include <QFileInfo>
|
||||
#include <QImageReader>
|
||||
#include <QRandomGenerator>
|
||||
#include "FileSystem.h"
|
||||
#include "Json.h"
|
||||
|
||||
@@ -79,7 +82,7 @@ JsonCatPack::JsonCatPack(QFileInfo& manifestInfo) : BasicCatPack(manifestInfo.di
|
||||
auto doc = Json::requireDocument(manifestInfo.absoluteFilePath(), "CatPack JSON file");
|
||||
const auto root = doc.object();
|
||||
m_name = Json::requireString(root, "name", "Catpack name");
|
||||
m_defaultPath = FS::PathCombine(path, Json::requireString(root, "default", "Default Cat"));
|
||||
m_default_path = FS::PathCombine(path, Json::requireString(root, "default", "Default Cat"));
|
||||
auto variants = Json::ensureArray(root, "variants", QJsonArray(), "Catpack Variants");
|
||||
for (auto v : variants) {
|
||||
auto variant = Json::ensureObject(v, QJsonObject(), "Cat variant");
|
||||
@@ -117,5 +120,21 @@ QString JsonCatPack::path(QDate now)
|
||||
if (startDate <= now && now <= endDate)
|
||||
return var.path;
|
||||
}
|
||||
return m_defaultPath;
|
||||
auto dInfo = QFileInfo(m_default_path);
|
||||
if (!dInfo.isDir())
|
||||
return m_default_path;
|
||||
|
||||
QStringList supportedImageFormats;
|
||||
for (auto format : QImageReader::supportedImageFormats()) {
|
||||
supportedImageFormats.append("*." + format);
|
||||
}
|
||||
|
||||
auto files = QDir(m_default_path).entryInfoList(supportedImageFormats, QDir::Files, QDir::Name);
|
||||
if (files.length() == 0)
|
||||
return "";
|
||||
auto idx = (now.dayOfYear() - 1) % files.length();
|
||||
auto isRandom = dInfo.fileName().compare("random", Qt::CaseInsensitive) == 0;
|
||||
if (isRandom)
|
||||
idx = QRandomGenerator::global()->bounded(0, files.length());
|
||||
return files[idx].absoluteFilePath();
|
||||
}
|
||||
|
||||
@@ -87,6 +87,6 @@ class JsonCatPack : public BasicCatPack {
|
||||
QString path(QDate now);
|
||||
|
||||
private:
|
||||
QString m_defaultPath;
|
||||
QString m_default_path;
|
||||
QList<Variant> m_variants;
|
||||
};
|
||||
|
||||
@@ -178,8 +178,8 @@ QList<ITheme*> ThemeManager::getValidApplicationThemes()
|
||||
QList<CatPack*> ThemeManager::getValidCatPacks()
|
||||
{
|
||||
QList<CatPack*> ret;
|
||||
ret.reserve(m_catPacks.size());
|
||||
for (auto&& [id, theme] : m_catPacks) {
|
||||
ret.reserve(m_cat_packs.size());
|
||||
for (auto&& [id, theme] : m_cat_packs) {
|
||||
ret.append(theme.get());
|
||||
}
|
||||
return ret;
|
||||
@@ -244,8 +244,8 @@ void ThemeManager::applyCurrentlySelectedTheme(bool initial)
|
||||
|
||||
QString ThemeManager::getCatPack(QString catName)
|
||||
{
|
||||
auto catIter = m_catPacks.find(!catName.isEmpty() ? catName : APPLICATION->settings()->get("BackgroundCat").toString());
|
||||
if (catIter != m_catPacks.end()) {
|
||||
auto catIter = m_cat_packs.find(!catName.isEmpty() ? catName : APPLICATION->settings()->get("BackgroundCat").toString());
|
||||
if (catIter != m_cat_packs.end()) {
|
||||
auto& catPack = catIter->second;
|
||||
themeDebugLog() << "applying catpack" << catPack->id();
|
||||
return catPack->path();
|
||||
@@ -253,14 +253,14 @@ QString ThemeManager::getCatPack(QString catName)
|
||||
themeWarningLog() << "Tried to get invalid catPack:" << catName;
|
||||
}
|
||||
|
||||
return m_catPacks.begin()->second->path();
|
||||
return m_cat_packs.begin()->second->path();
|
||||
}
|
||||
|
||||
QString ThemeManager::addCatPack(std::unique_ptr<CatPack> catPack)
|
||||
{
|
||||
QString id = catPack->id();
|
||||
if (m_catPacks.find(id) == m_catPacks.end())
|
||||
m_catPacks.emplace(id, std::move(catPack));
|
||||
if (m_cat_packs.find(id) == m_cat_packs.end())
|
||||
m_cat_packs.emplace(id, std::move(catPack));
|
||||
else
|
||||
themeWarningLog() << "CatPack(" << id << ") not added to prevent id duplication";
|
||||
return id;
|
||||
|
||||
@@ -61,7 +61,7 @@ class ThemeManager {
|
||||
QDir m_iconThemeFolder{ "iconthemes" };
|
||||
QDir m_applicationThemeFolder{ "themes" };
|
||||
QDir m_catPacksFolder{ "catpacks" };
|
||||
std::map<QString, std::unique_ptr<CatPack>> m_catPacks;
|
||||
std::map<QString, std::unique_ptr<CatPack>> m_cat_packs;
|
||||
|
||||
void initializeThemes();
|
||||
void initializeCatPacks();
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "LogView.h"
|
||||
#include <QScrollBar>
|
||||
#include <QTextBlock>
|
||||
#include <QTextDocumentFragment>
|
||||
|
||||
LogView::LogView(QWidget* parent) : QPlainTextEdit(parent)
|
||||
{
|
||||
@@ -117,6 +118,9 @@ void LogView::rowsAboutToBeInserted(const QModelIndex& parent, int first, int la
|
||||
|
||||
void LogView::rowsInserted(const QModelIndex& parent, int first, int last)
|
||||
{
|
||||
QTextDocument document;
|
||||
QTextCursor cursor(&document);
|
||||
|
||||
for (int i = first; i <= last; i++) {
|
||||
auto idx = m_model->index(i, 0, parent);
|
||||
auto text = m_model->data(idx, Qt::DisplayRole).toString();
|
||||
@@ -133,11 +137,16 @@ void LogView::rowsInserted(const QModelIndex& parent, int first, int last)
|
||||
if (bg.isValid()) {
|
||||
format.setBackground(bg.value<QColor>());
|
||||
}
|
||||
auto workCursor = textCursor();
|
||||
workCursor.movePosition(QTextCursor::End);
|
||||
workCursor.insertText(text, format);
|
||||
workCursor.insertBlock();
|
||||
cursor.movePosition(QTextCursor::End);
|
||||
cursor.insertText(text, format);
|
||||
cursor.insertBlock();
|
||||
}
|
||||
|
||||
QTextDocumentFragment fragment(&document);
|
||||
QTextCursor workCursor = textCursor();
|
||||
workCursor.movePosition(QTextCursor::End);
|
||||
workCursor.insertFragment(fragment);
|
||||
|
||||
if (m_scroll && !m_scrolling) {
|
||||
m_scrolling = true;
|
||||
QMetaObject::invokeMethod(this, "scrollToBottom", Qt::QueuedConnection);
|
||||
|
||||
Reference in New Issue
Block a user