Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into welcome_background
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
This commit is contained in:
@ -1,13 +1,11 @@
|
||||
#include "ColorCache.h"
|
||||
|
||||
|
||||
/**
|
||||
* Blend the color with the front color, adapting to the back color
|
||||
*/
|
||||
QColor ColorCache::blend(QColor color)
|
||||
{
|
||||
if (Rainbow::luma(m_front) > Rainbow::luma(m_back))
|
||||
{
|
||||
if (Rainbow::luma(m_front) > Rainbow::luma(m_back)) {
|
||||
// for dark color schemes, produce a fitting color first
|
||||
color = Rainbow::tint(m_front, color, 0.5);
|
||||
}
|
||||
@ -27,8 +25,7 @@ QColor ColorCache::blendBackground(QColor color)
|
||||
void ColorCache::recolorAll()
|
||||
{
|
||||
auto iter = m_colors.begin();
|
||||
while(iter != m_colors.end())
|
||||
{
|
||||
while (iter != m_colors.end()) {
|
||||
iter->front = blend(iter->original);
|
||||
iter->back = blendBackground(iter->original);
|
||||
}
|
||||
|
@ -1,12 +1,11 @@
|
||||
#pragma once
|
||||
#include <QtGui/QColor>
|
||||
#include <rainbow.h>
|
||||
#include <MessageLevel.h>
|
||||
#include <rainbow.h>
|
||||
#include <QMap>
|
||||
#include <QtGui/QColor>
|
||||
|
||||
class ColorCache
|
||||
{
|
||||
public:
|
||||
class ColorCache {
|
||||
public:
|
||||
ColorCache(QColor front, QColor back, qreal bias)
|
||||
{
|
||||
m_front = front;
|
||||
@ -14,15 +13,11 @@ public:
|
||||
m_bias = bias;
|
||||
};
|
||||
|
||||
void addColor(int key, QColor color)
|
||||
{
|
||||
m_colors[key] = {color, blend(color), blendBackground(color)};
|
||||
}
|
||||
void addColor(int key, QColor color) { m_colors[key] = { color, blend(color), blendBackground(color) }; }
|
||||
|
||||
void setForeground(QColor front)
|
||||
{
|
||||
if(m_front != front)
|
||||
{
|
||||
if (m_front != front) {
|
||||
m_front = front;
|
||||
recolorAll();
|
||||
}
|
||||
@ -30,8 +25,7 @@ public:
|
||||
|
||||
void setBackground(QColor back)
|
||||
{
|
||||
if(m_back != back)
|
||||
{
|
||||
if (m_back != back) {
|
||||
m_back = back;
|
||||
recolorAll();
|
||||
}
|
||||
@ -40,8 +34,7 @@ public:
|
||||
QColor getFront(int key)
|
||||
{
|
||||
auto iter = m_colors.find(key);
|
||||
if(iter == m_colors.end())
|
||||
{
|
||||
if (iter == m_colors.end()) {
|
||||
return QColor();
|
||||
}
|
||||
return (*iter).front;
|
||||
@ -50,8 +43,7 @@ public:
|
||||
QColor getBack(int key)
|
||||
{
|
||||
auto iter = m_colors.find(key);
|
||||
if(iter == m_colors.end())
|
||||
{
|
||||
if (iter == m_colors.end()) {
|
||||
return QColor();
|
||||
}
|
||||
return (*iter).back;
|
||||
@ -67,29 +59,26 @@ public:
|
||||
*/
|
||||
QColor blendBackground(QColor color);
|
||||
|
||||
protected:
|
||||
protected:
|
||||
void recolorAll();
|
||||
|
||||
protected:
|
||||
struct ColorEntry
|
||||
{
|
||||
protected:
|
||||
struct ColorEntry {
|
||||
QColor original;
|
||||
QColor front;
|
||||
QColor back;
|
||||
};
|
||||
|
||||
protected:
|
||||
protected:
|
||||
qreal m_bias;
|
||||
QColor m_front;
|
||||
QColor m_back;
|
||||
QMap<int, ColorEntry> m_colors;
|
||||
};
|
||||
|
||||
class LogColorCache : public ColorCache
|
||||
{
|
||||
public:
|
||||
LogColorCache(QColor front, QColor back)
|
||||
: ColorCache(front, back, 1.0)
|
||||
class LogColorCache : public ColorCache {
|
||||
public:
|
||||
LogColorCache(QColor front, QColor back) : ColorCache(front, back, 1.0)
|
||||
{
|
||||
addColor((int)MessageLevel::Launcher, QColor("purple"));
|
||||
addColor((int)MessageLevel::Debug, QColor("green"));
|
||||
@ -101,8 +90,7 @@ public:
|
||||
|
||||
QColor getFront(MessageLevel::Enum level)
|
||||
{
|
||||
if(!m_colors.contains((int) level))
|
||||
{
|
||||
if (!m_colors.contains((int)level)) {
|
||||
return ColorCache::getFront((int)MessageLevel::Message);
|
||||
}
|
||||
return ColorCache::getFront((int)level);
|
||||
@ -110,8 +98,7 @@ public:
|
||||
|
||||
QColor getBack(MessageLevel::Enum level)
|
||||
{
|
||||
if(level == MessageLevel::Fatal)
|
||||
{
|
||||
if (level == MessageLevel::Fatal) {
|
||||
return QColor(Qt::black);
|
||||
}
|
||||
return QColor(Qt::transparent);
|
||||
|
@ -37,21 +37,21 @@
|
||||
|
||||
#include "GuiUtil.h"
|
||||
|
||||
#include <QClipboard>
|
||||
#include <QApplication>
|
||||
#include <QClipboard>
|
||||
#include <QFileDialog>
|
||||
#include <QStandardPaths>
|
||||
|
||||
#include "ui/dialogs/ProgressDialog.h"
|
||||
#include "ui/dialogs/CustomMessageBox.h"
|
||||
#include "net/PasteUpload.h"
|
||||
#include "ui/dialogs/CustomMessageBox.h"
|
||||
#include "ui/dialogs/ProgressDialog.h"
|
||||
|
||||
#include "Application.h"
|
||||
#include <settings/SettingsObject.h>
|
||||
#include <DesktopServices.h>
|
||||
#include <BuildConfig.h>
|
||||
#include <DesktopServices.h>
|
||||
#include <settings/SettingsObject.h>
|
||||
#include "Application.h"
|
||||
|
||||
std::optional<QString> GuiUtil::uploadPaste(const QString &name, const QString &text, QWidget *parentWidget)
|
||||
std::optional<QString> GuiUtil::uploadPaste(const QString& name, const QString& text, QWidget* parentWidget)
|
||||
{
|
||||
ProgressDialog dialog(parentWidget);
|
||||
auto pasteTypeSetting = static_cast<PasteUpload::PasteType>(APPLICATION->settings()->get("PastebinType").toInt());
|
||||
@ -64,8 +64,7 @@ std::optional<QString> GuiUtil::uploadPaste(const QString &name, const QString &
|
||||
else
|
||||
baseUrl = pasteCustomAPIBaseSetting;
|
||||
|
||||
if (baseUrl.isValid())
|
||||
{
|
||||
if (baseUrl.isValid()) {
|
||||
auto response = CustomMessageBox::selectable(parentWidget, QObject::tr("Confirm Upload"),
|
||||
QObject::tr("You are about to upload \"%1\" to %2.\n"
|
||||
"You should double-check for personal information.\n\n"
|
||||
@ -82,41 +81,38 @@ std::optional<QString> GuiUtil::uploadPaste(const QString &name, const QString &
|
||||
std::unique_ptr<PasteUpload> paste(new PasteUpload(parentWidget, text, pasteCustomAPIBaseSetting, pasteTypeSetting));
|
||||
|
||||
dialog.execWithTask(paste.get());
|
||||
if (!paste->wasSuccessful())
|
||||
{
|
||||
CustomMessageBox::selectable(
|
||||
parentWidget,
|
||||
QObject::tr("Upload failed"),
|
||||
paste->failReason(),
|
||||
QMessageBox::Critical
|
||||
)->exec();
|
||||
if (!paste->wasSuccessful()) {
|
||||
CustomMessageBox::selectable(parentWidget, QObject::tr("Upload failed"), paste->failReason(), QMessageBox::Critical)->exec();
|
||||
return QString();
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
const QString link = paste->pasteLink();
|
||||
setClipboardText(link);
|
||||
CustomMessageBox::selectable(
|
||||
parentWidget, QObject::tr("Upload finished"),
|
||||
QObject::tr("The <a href=\"%1\">link to the uploaded log</a> has been placed in your clipboard.").arg(link),
|
||||
QMessageBox::Information)->exec();
|
||||
QMessageBox::Information)
|
||||
->exec();
|
||||
return link;
|
||||
}
|
||||
}
|
||||
|
||||
void GuiUtil::setClipboardText(const QString &text)
|
||||
void GuiUtil::setClipboardText(const QString& text)
|
||||
{
|
||||
QApplication::clipboard()->setText(text);
|
||||
}
|
||||
|
||||
static QStringList BrowseForFileInternal(QString context, QString caption, QString filter, QString defaultPath, QWidget *parentWidget, bool single)
|
||||
static QStringList BrowseForFileInternal(QString context,
|
||||
QString caption,
|
||||
QString filter,
|
||||
QString defaultPath,
|
||||
QWidget* parentWidget,
|
||||
bool single)
|
||||
{
|
||||
static QMap<QString, QString> savedPaths;
|
||||
|
||||
QFileDialog w(parentWidget, caption);
|
||||
QSet<QString> locations;
|
||||
auto f = [&](QStandardPaths::StandardLocation l)
|
||||
{
|
||||
auto f = [&](QStandardPaths::StandardLocation l) {
|
||||
QString location = QStandardPaths::writableLocation(l);
|
||||
QFileInfo finfo(location);
|
||||
if (!finfo.exists()) {
|
||||
@ -129,8 +125,7 @@ static QStringList BrowseForFileInternal(QString context, QString caption, QStri
|
||||
f(QStandardPaths::DownloadLocation);
|
||||
f(QStandardPaths::HomeLocation);
|
||||
QList<QUrl> urls;
|
||||
for (auto location : locations)
|
||||
{
|
||||
for (auto location : locations) {
|
||||
urls.append(QUrl::fromLocalFile(location));
|
||||
}
|
||||
urls.append(QUrl::fromLocalFile(defaultPath));
|
||||
@ -140,27 +135,21 @@ static QStringList BrowseForFileInternal(QString context, QString caption, QStri
|
||||
w.setNameFilter(filter);
|
||||
|
||||
QString pathToOpen;
|
||||
if(savedPaths.contains(context))
|
||||
{
|
||||
if (savedPaths.contains(context)) {
|
||||
pathToOpen = savedPaths[context];
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
pathToOpen = defaultPath;
|
||||
}
|
||||
if(!pathToOpen.isEmpty())
|
||||
{
|
||||
if (!pathToOpen.isEmpty()) {
|
||||
QFileInfo finfo(pathToOpen);
|
||||
if(finfo.exists() && finfo.isDir())
|
||||
{
|
||||
if (finfo.exists() && finfo.isDir()) {
|
||||
w.setDirectory(finfo.absoluteFilePath());
|
||||
}
|
||||
}
|
||||
|
||||
w.setSidebarUrls(urls);
|
||||
|
||||
if (w.exec())
|
||||
{
|
||||
if (w.exec()) {
|
||||
savedPaths[context] = w.directory().absolutePath();
|
||||
return w.selectedFiles();
|
||||
}
|
||||
@ -168,18 +157,16 @@ static QStringList BrowseForFileInternal(QString context, QString caption, QStri
|
||||
return {};
|
||||
}
|
||||
|
||||
QString GuiUtil::BrowseForFile(QString context, QString caption, QString filter, QString defaultPath, QWidget *parentWidget)
|
||||
QString GuiUtil::BrowseForFile(QString context, QString caption, QString filter, QString defaultPath, QWidget* parentWidget)
|
||||
{
|
||||
auto resultList = BrowseForFileInternal(context, caption, filter, defaultPath, parentWidget, true);
|
||||
if(resultList.size())
|
||||
{
|
||||
if (resultList.size()) {
|
||||
return resultList[0];
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
|
||||
QStringList GuiUtil::BrowseForFiles(QString context, QString caption, QString filter, QString defaultPath, QWidget *parentWidget)
|
||||
QStringList GuiUtil::BrowseForFiles(QString context, QString caption, QString filter, QString defaultPath, QWidget* parentWidget)
|
||||
{
|
||||
return BrowseForFileInternal(context, caption, filter, defaultPath, parentWidget, false);
|
||||
}
|
||||
|
@ -3,10 +3,9 @@
|
||||
#include <QWidget>
|
||||
#include <optional>
|
||||
|
||||
namespace GuiUtil
|
||||
{
|
||||
std::optional<QString> uploadPaste(const QString &name, const QString &text, QWidget *parentWidget);
|
||||
void setClipboardText(const QString &text);
|
||||
QStringList BrowseForFiles(QString context, QString caption, QString filter, QString defaultPath, QWidget *parentWidget);
|
||||
QString BrowseForFile(QString context, QString caption, QString filter, QString defaultPath, QWidget *parentWidget);
|
||||
}
|
||||
namespace GuiUtil {
|
||||
std::optional<QString> uploadPaste(const QString& name, const QString& text, QWidget* parentWidget);
|
||||
void setClipboardText(const QString& text);
|
||||
QStringList BrowseForFiles(QString context, QString caption, QString filter, QString defaultPath, QWidget* parentWidget);
|
||||
QString BrowseForFile(QString context, QString caption, QString filter, QString defaultPath, QWidget* parentWidget);
|
||||
} // namespace GuiUtil
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
/*
|
||||
* PolyMC - Minecraft Launcher
|
||||
* Prism Launcher - Minecraft Launcher
|
||||
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
@ -36,12 +36,12 @@
|
||||
#include "InstanceWindow.h"
|
||||
#include "Application.h"
|
||||
|
||||
#include <QScrollBar>
|
||||
#include <QMessageBox>
|
||||
#include <QHBoxLayout>
|
||||
#include <QPushButton>
|
||||
#include <qlayoutitem.h>
|
||||
#include <QCloseEvent>
|
||||
#include <QHBoxLayout>
|
||||
#include <QMessageBox>
|
||||
#include <QPushButton>
|
||||
#include <QScrollBar>
|
||||
|
||||
#include "ui/dialogs/CustomMessageBox.h"
|
||||
#include "ui/dialogs/ProgressDialog.h"
|
||||
@ -51,8 +51,7 @@
|
||||
|
||||
#include "icons/IconList.h"
|
||||
|
||||
InstanceWindow::InstanceWindow(InstancePtr instance, QWidget *parent)
|
||||
: QMainWindow(parent), m_instance(instance)
|
||||
InstanceWindow::InstanceWindow(InstancePtr instance, QWidget* parent) : QMainWindow(parent), m_instance(instance)
|
||||
{
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
||||
@ -143,8 +142,7 @@ InstanceWindow::InstanceWindow(InstancePtr instance, QWidget *parent)
|
||||
|
||||
void InstanceWindow::on_instanceStatusChanged(BaseInstance::Status, BaseInstance::Status newStatus)
|
||||
{
|
||||
if(newStatus == BaseInstance::Status::Gone)
|
||||
{
|
||||
if (newStatus == BaseInstance::Status::Gone) {
|
||||
m_doNotSave = true;
|
||||
close();
|
||||
}
|
||||
@ -152,25 +150,20 @@ void InstanceWindow::on_instanceStatusChanged(BaseInstance::Status, BaseInstance
|
||||
|
||||
void InstanceWindow::updateLaunchButtons()
|
||||
{
|
||||
if(m_instance->isRunning())
|
||||
{
|
||||
if (m_instance->isRunning()) {
|
||||
m_launchOfflineButton->setEnabled(false);
|
||||
m_launchDemoButton->setEnabled(false);
|
||||
m_killButton->setText(tr("Kill"));
|
||||
m_killButton->setObjectName("killButton");
|
||||
m_killButton->setToolTip(tr("Kill the running instance"));
|
||||
}
|
||||
else if(!m_instance->canLaunch())
|
||||
{
|
||||
} else if (!m_instance->canLaunch()) {
|
||||
m_launchOfflineButton->setEnabled(false);
|
||||
m_launchDemoButton->setEnabled(false);
|
||||
m_killButton->setText(tr("Launch"));
|
||||
m_killButton->setObjectName("launchButton");
|
||||
m_killButton->setToolTip(tr("Launch the instance"));
|
||||
m_killButton->setEnabled(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
m_launchOfflineButton->setEnabled(true);
|
||||
|
||||
// Disable demo-mode if not available.
|
||||
@ -207,7 +200,7 @@ void InstanceWindow::runningStateChanged(bool running)
|
||||
{
|
||||
updateLaunchButtons();
|
||||
m_container->refreshContainer();
|
||||
if(running) {
|
||||
if (running) {
|
||||
selectPage("log");
|
||||
}
|
||||
}
|
||||
@ -217,16 +210,14 @@ void InstanceWindow::on_closeButton_clicked()
|
||||
close();
|
||||
}
|
||||
|
||||
void InstanceWindow::closeEvent(QCloseEvent *event)
|
||||
void InstanceWindow::closeEvent(QCloseEvent* event)
|
||||
{
|
||||
bool proceed = true;
|
||||
if(!m_doNotSave)
|
||||
{
|
||||
if (!m_doNotSave) {
|
||||
proceed &= m_container->prepareToClose();
|
||||
}
|
||||
|
||||
if(!proceed)
|
||||
{
|
||||
if (!proceed) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -243,12 +234,9 @@ bool InstanceWindow::saveAll()
|
||||
|
||||
void InstanceWindow::on_btnKillMinecraft_clicked()
|
||||
{
|
||||
if(m_instance->isRunning())
|
||||
{
|
||||
if (m_instance->isRunning()) {
|
||||
APPLICATION->kill(m_instance);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
APPLICATION->launch(m_instance, true, false, nullptr);
|
||||
}
|
||||
}
|
||||
@ -268,14 +256,11 @@ void InstanceWindow::refreshContainer()
|
||||
m_container->refreshContainer();
|
||||
}
|
||||
|
||||
InstanceWindow::~InstanceWindow()
|
||||
{
|
||||
}
|
||||
InstanceWindow::~InstanceWindow() {}
|
||||
|
||||
bool InstanceWindow::requestClose()
|
||||
{
|
||||
if(m_container->prepareToClose())
|
||||
{
|
||||
if (m_container->prepareToClose()) {
|
||||
close();
|
||||
return true;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
/*
|
||||
* PolyMC - Minecraft Launcher
|
||||
* Prism Launcher - Minecraft Launcher
|
||||
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
@ -47,12 +47,11 @@
|
||||
|
||||
class QPushButton;
|
||||
class PageContainer;
|
||||
class InstanceWindow : public QMainWindow, public BasePageContainer
|
||||
{
|
||||
class InstanceWindow : public QMainWindow, public BasePageContainer {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit InstanceWindow(InstancePtr proc, QWidget *parent = 0);
|
||||
public:
|
||||
explicit InstanceWindow(InstancePtr proc, QWidget* parent = 0);
|
||||
virtual ~InstanceWindow();
|
||||
|
||||
bool selectPage(QString pageId) override;
|
||||
@ -66,11 +65,10 @@ public:
|
||||
// request closing the window (from a page)
|
||||
bool requestClose() override;
|
||||
|
||||
signals:
|
||||
signals:
|
||||
void isClosing();
|
||||
|
||||
private
|
||||
slots:
|
||||
private slots:
|
||||
void on_closeButton_clicked();
|
||||
void on_btnKillMinecraft_clicked();
|
||||
void on_btnLaunchMinecraftOffline_clicked();
|
||||
@ -80,19 +78,19 @@ slots:
|
||||
void runningStateChanged(bool running);
|
||||
void on_instanceStatusChanged(BaseInstance::Status, BaseInstance::Status newStatus);
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *) override;
|
||||
protected:
|
||||
void closeEvent(QCloseEvent*) override;
|
||||
|
||||
private:
|
||||
private:
|
||||
void updateLaunchButtons();
|
||||
|
||||
private:
|
||||
private:
|
||||
shared_qobject_ptr<LaunchTask> m_proc;
|
||||
InstancePtr m_instance;
|
||||
bool m_doNotSave = false;
|
||||
PageContainer *m_container = nullptr;
|
||||
QPushButton *m_closeButton = nullptr;
|
||||
QPushButton *m_killButton = nullptr;
|
||||
QPushButton *m_launchOfflineButton = nullptr;
|
||||
QPushButton *m_launchDemoButton = nullptr;
|
||||
PageContainer* m_container = nullptr;
|
||||
QPushButton* m_closeButton = nullptr;
|
||||
QPushButton* m_killButton = nullptr;
|
||||
QPushButton* m_launchOfflineButton = nullptr;
|
||||
QPushButton* m_launchDemoButton = nullptr;
|
||||
};
|
||||
|
@ -1342,16 +1342,10 @@ void MainWindow::on_actionExportInstanceFlamePack_triggered()
|
||||
if (m_selectedInstance) {
|
||||
auto instance = dynamic_cast<MinecraftInstance*>(m_selectedInstance.get());
|
||||
if (instance) {
|
||||
QString errorMsg;
|
||||
if (instance->getPackProfile()->getComponent("org.quiltmc.quilt-loader")) {
|
||||
errorMsg = tr("Quilt is currently not supported by CurseForge modpacks.");
|
||||
} else if (auto cmp = instance->getPackProfile()->getComponent("net.minecraft");
|
||||
cmp && cmp->getVersionFile() && cmp->getVersionFile()->type == "snapshot") {
|
||||
errorMsg = tr("Snapshots are currently not supported by CurseForge modpacks.");
|
||||
}
|
||||
if (!errorMsg.isEmpty()) {
|
||||
QMessageBox msgBox;
|
||||
msgBox.setText(errorMsg);
|
||||
if (auto cmp = instance->getPackProfile()->getComponent("net.minecraft");
|
||||
cmp && cmp->getVersionFile() && cmp->getVersionFile()->type == "snapshot") {
|
||||
QMessageBox msgBox(this);
|
||||
msgBox.setText("Snapshots are currently not supported by CurseForge modpacks.");
|
||||
msgBox.exec();
|
||||
return;
|
||||
}
|
||||
|
@ -63,34 +63,32 @@ class KonamiCode;
|
||||
class InstanceTask;
|
||||
class LabeledToolButton;
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
namespace Ui {
|
||||
class MainWindow;
|
||||
}
|
||||
class MainWindow : public QMainWindow
|
||||
{
|
||||
class MainWindow : public QMainWindow {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MainWindow(QWidget *parent = 0);
|
||||
public:
|
||||
explicit MainWindow(QWidget* parent = 0);
|
||||
~MainWindow();
|
||||
|
||||
bool eventFilter(QObject *obj, QEvent *ev) override;
|
||||
void closeEvent(QCloseEvent *event) override;
|
||||
void changeEvent(QEvent * event) override;
|
||||
bool eventFilter(QObject* obj, QEvent* ev) override;
|
||||
void closeEvent(QCloseEvent* event) override;
|
||||
void changeEvent(QEvent* event) override;
|
||||
|
||||
void checkInstancePathForProblems();
|
||||
|
||||
void updatesAllowedChanged(bool allowed);
|
||||
|
||||
void processURLs(QList<QUrl> urls);
|
||||
signals:
|
||||
signals:
|
||||
void isClosing();
|
||||
|
||||
protected:
|
||||
QMenu * createPopupMenu() override;
|
||||
protected:
|
||||
QMenu* createPopupMenu() override;
|
||||
|
||||
private slots:
|
||||
private slots:
|
||||
void onCatToggled(bool);
|
||||
|
||||
void onCatChanged(int);
|
||||
@ -131,9 +129,9 @@ private slots:
|
||||
|
||||
void on_actionClearMetadata_triggered();
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
#ifdef Q_OS_MAC
|
||||
void on_actionAddToPATH_triggered();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void on_actionOpenWiki_triggered();
|
||||
|
||||
@ -154,7 +152,10 @@ private slots:
|
||||
void deleteGroup();
|
||||
void undoTrashInstance();
|
||||
|
||||
inline void on_actionExportInstance_triggered() { on_actionExportInstanceZip_triggered(); }
|
||||
inline void on_actionExportInstance_triggered()
|
||||
{
|
||||
on_actionExportInstanceZip_triggered();
|
||||
}
|
||||
void on_actionExportInstanceZip_triggered();
|
||||
void on_actionExportInstanceMrPack_triggered();
|
||||
void on_actionExportInstanceFlamePack_triggered();
|
||||
@ -173,7 +174,7 @@ private slots:
|
||||
*/
|
||||
void iconUpdated(QString);
|
||||
|
||||
void showInstanceContextMenu(const QPoint &);
|
||||
void showInstanceContextMenu(const QPoint&);
|
||||
|
||||
void updateMainToolBar();
|
||||
|
||||
@ -183,15 +184,15 @@ private slots:
|
||||
|
||||
void instanceActivated(QModelIndex);
|
||||
|
||||
void instanceChanged(const QModelIndex ¤t, const QModelIndex &previous);
|
||||
void instanceChanged(const QModelIndex& current, const QModelIndex& previous);
|
||||
|
||||
void instanceSelectRequest(QString id);
|
||||
|
||||
void instanceDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
|
||||
void instanceDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight);
|
||||
|
||||
void selectionBad();
|
||||
|
||||
void startTask(Task *task);
|
||||
void startTask(Task* task);
|
||||
|
||||
void defaultAccountChanged();
|
||||
|
||||
@ -201,7 +202,6 @@ private slots:
|
||||
|
||||
void updateNewsLabel();
|
||||
|
||||
|
||||
void konamiTriggered();
|
||||
|
||||
void globalSettingsClosed();
|
||||
@ -209,38 +209,38 @@ private slots:
|
||||
void lockToolbars(bool);
|
||||
|
||||
#ifndef Q_OS_MAC
|
||||
void keyReleaseEvent(QKeyEvent *event) override;
|
||||
void keyReleaseEvent(QKeyEvent* event) override;
|
||||
#endif
|
||||
|
||||
void refreshCurrentInstance(bool running);
|
||||
|
||||
private:
|
||||
private:
|
||||
void retranslateUi();
|
||||
|
||||
void addInstance(QString url = QString());
|
||||
void activateInstance(InstancePtr instance);
|
||||
void setCatBackground(bool enabled);
|
||||
void updateInstanceToolIcon(QString new_icon);
|
||||
void setSelectedInstanceById(const QString &id);
|
||||
void setSelectedInstanceById(const QString& id);
|
||||
void updateStatusCenter();
|
||||
void setInstanceActionsEnabled(bool enabled);
|
||||
|
||||
void runModalTask(Task *task);
|
||||
void instanceFromInstanceTask(InstanceTask *task);
|
||||
void runModalTask(Task* task);
|
||||
void instanceFromInstanceTask(InstanceTask* task);
|
||||
void finalizeInstance(InstancePtr inst);
|
||||
|
||||
private:
|
||||
Ui::MainWindow *ui;
|
||||
private:
|
||||
Ui::MainWindow* ui;
|
||||
// these are managed by Qt's memory management model!
|
||||
InstanceView *view = nullptr;
|
||||
InstanceProxyModel *proxymodel = nullptr;
|
||||
QToolButton *newsLabel = nullptr;
|
||||
QLabel *m_statusLeft = nullptr;
|
||||
QLabel *m_statusCenter = nullptr;
|
||||
LabeledToolButton *changeIconButton = nullptr;
|
||||
LabeledToolButton *renameButton = nullptr;
|
||||
QToolButton *helpMenuButton = nullptr;
|
||||
KonamiCode * secretEventFilter = nullptr;
|
||||
InstanceView* view = nullptr;
|
||||
InstanceProxyModel* proxymodel = nullptr;
|
||||
QToolButton* newsLabel = nullptr;
|
||||
QLabel* m_statusLeft = nullptr;
|
||||
QLabel* m_statusCenter = nullptr;
|
||||
LabeledToolButton* changeIconButton = nullptr;
|
||||
LabeledToolButton* renameButton = nullptr;
|
||||
QToolButton* helpMenuButton = nullptr;
|
||||
KonamiCode* secretEventFilter = nullptr;
|
||||
|
||||
std::shared_ptr<Setting> instanceToolbarSetting = nullptr;
|
||||
|
||||
@ -250,5 +250,5 @@ private:
|
||||
QString m_currentInstIcon;
|
||||
|
||||
// managed by the application object
|
||||
Task *m_versionLoadTask = nullptr;
|
||||
Task* m_versionLoadTask = nullptr;
|
||||
};
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
/*
|
||||
* PolyMC - Minecraft Launcher
|
||||
* Prism Launcher - Minecraft Launcher
|
||||
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
@ -34,26 +34,28 @@
|
||||
*/
|
||||
|
||||
#include "AboutDialog.h"
|
||||
#include "BuildConfig.h"
|
||||
#include "ui_AboutDialog.h"
|
||||
#include <QIcon>
|
||||
#include "Application.h"
|
||||
#include "BuildConfig.h"
|
||||
#include "Markdown.h"
|
||||
#include "ui_AboutDialog.h"
|
||||
|
||||
#include <net/NetJob.h>
|
||||
#include <qobject.h>
|
||||
|
||||
namespace {
|
||||
QString getLink(QString link, QString name) {
|
||||
QString getLink(QString link, QString name)
|
||||
{
|
||||
return QString("<<a href='%1'>%2</a>>").arg(link).arg(name);
|
||||
}
|
||||
|
||||
QString getWebsite(QString link) {
|
||||
QString getWebsite(QString link)
|
||||
{
|
||||
return getLink(link, QObject::tr("Website"));
|
||||
}
|
||||
|
||||
QString getGitHub(QString username) {
|
||||
QString getGitHub(QString username)
|
||||
{
|
||||
return getLink("https://github.com/" + username, "GitHub");
|
||||
}
|
||||
|
||||
@ -70,19 +72,19 @@ QString getCreditsHtml()
|
||||
|
||||
//: %1 is the name of the launcher, determined at build time, e.g. "Prism Launcher Developers"
|
||||
stream << "<h3>" << QObject::tr("%1 Developers", "About Credits").arg(BuildConfig.LAUNCHER_DISPLAYNAME) << "</h3>\n";
|
||||
stream << QString("<p>Sefa Eyeoglu (Scrumplex) %1</p>\n") .arg(getWebsite("https://scrumplex.net"));
|
||||
stream << QString("<p>d-513 %1</p>\n") .arg(getGitHub("d-513"));
|
||||
stream << QString("<p>txtsd %1</p>\n") .arg(getWebsite("https://ihavea.quest"));
|
||||
stream << QString("<p>timoreo %1</p>\n") .arg(getGitHub("timoreo22"));
|
||||
stream << QString("<p>Ezekiel Smith (ZekeSmith) %1</p>\n") .arg(getGitHub("ZekeSmith"));
|
||||
stream << QString("<p>cozyGalvinism %1</p>\n") .arg(getGitHub("cozyGalvinism"));
|
||||
stream << QString("<p>DioEgizio %1</p>\n") .arg(getGitHub("DioEgizio"));
|
||||
stream << QString("<p>flowln %1</p>\n") .arg(getGitHub("flowln"));
|
||||
stream << QString("<p>ViRb3 %1</p>\n") .arg(getGitHub("ViRb3"));
|
||||
stream << QString("<p>Rachel Powers (Ryex) %1</p>\n") .arg(getGitHub("Ryex"));
|
||||
stream << QString("<p>TayouVR %1</p>\n") .arg(getGitHub("TayouVR"));
|
||||
stream << QString("<p>TheKodeToad %1</p>\n") .arg(getGitHub("TheKodeToad"));
|
||||
stream << QString("<p>getchoo %1</p>\n") .arg(getGitHub("getchoo"));
|
||||
stream << QString("<p>Sefa Eyeoglu (Scrumplex) %1</p>\n").arg(getWebsite("https://scrumplex.net"));
|
||||
stream << QString("<p>d-513 %1</p>\n").arg(getGitHub("d-513"));
|
||||
stream << QString("<p>txtsd %1</p>\n").arg(getWebsite("https://ihavea.quest"));
|
||||
stream << QString("<p>timoreo %1</p>\n").arg(getGitHub("timoreo22"));
|
||||
stream << QString("<p>Ezekiel Smith (ZekeSmith) %1</p>\n").arg(getGitHub("ZekeSmith"));
|
||||
stream << QString("<p>cozyGalvinism %1</p>\n").arg(getGitHub("cozyGalvinism"));
|
||||
stream << QString("<p>DioEgizio %1</p>\n").arg(getGitHub("DioEgizio"));
|
||||
stream << QString("<p>flowln %1</p>\n").arg(getGitHub("flowln"));
|
||||
stream << QString("<p>ViRb3 %1</p>\n").arg(getGitHub("ViRb3"));
|
||||
stream << QString("<p>Rachel Powers (Ryex) %1</p>\n").arg(getGitHub("Ryex"));
|
||||
stream << QString("<p>TayouVR %1</p>\n").arg(getGitHub("TayouVR"));
|
||||
stream << QString("<p>TheKodeToad %1</p>\n").arg(getGitHub("TheKodeToad"));
|
||||
stream << QString("<p>getchoo %1</p>\n").arg(getGitHub("getchoo"));
|
||||
stream << "<br />\n";
|
||||
|
||||
// TODO: possibly retrieve from git history at build time?
|
||||
@ -96,20 +98,21 @@ QString getCreditsHtml()
|
||||
stream << "<br />\n";
|
||||
|
||||
stream << "<h3>" << QObject::tr("With thanks to", "About Credits") << "</h3>\n";
|
||||
stream << QString("<p>Boba %1</p>\n") .arg(getWebsite("https://bobaonline.neocities.org/"));
|
||||
stream << QString("<p>Davi Rafael %1</p>\n") .arg(getWebsite("https://auti.one/"));
|
||||
stream << QString("<p>Fulmine %1</p>\n") .arg(getWebsite("https://www.fulmine.xyz/"));
|
||||
stream << QString("<p>ely %1</p>\n") .arg(getGitHub("elyrodso"));
|
||||
stream << QString("<p>gon sawa %1</p>\n") .arg(getGitHub("gonsawa"));
|
||||
stream << QString("<p>Boba %1</p>\n").arg(getWebsite("https://bobaonline.neocities.org/"));
|
||||
stream << QString("<p>Davi Rafael %1</p>\n").arg(getWebsite("https://auti.one/"));
|
||||
stream << QString("<p>Fulmine %1</p>\n").arg(getWebsite("https://www.fulmine.xyz/"));
|
||||
stream << QString("<p>ely %1</p>\n").arg(getGitHub("elyrodso"));
|
||||
stream << QString("<p>gon sawa %1</p>\n").arg(getGitHub("gonsawa"));
|
||||
stream << QString("<p>Pankakes</p>\n");
|
||||
stream << QString("<p>tobimori %1</p>\n") .arg(getGitHub("tobimori"));
|
||||
stream << QString("<p>tobimori %1</p>\n").arg(getGitHub("tobimori"));
|
||||
stream << "<p>Orochimarufan <<a href='mailto:orochimarufan.x3@gmail.com'>orochimarufan.x3@gmail.com</a>></p>\n";
|
||||
stream << "<p>TakSuyu <<a href='mailto:taksuyu@gmail.com'>taksuyu@gmail.com</a>></p>\n";
|
||||
stream << "<p>Kilobyte <<a href='mailto:stiepen22@gmx.de'>stiepen22@gmx.de</a>></p>\n";
|
||||
stream << "<p>Rootbear75 <<a href='https://twitter.com/rootbear75'>@rootbear75</a>></p>\n";
|
||||
stream << "<p>Zeker Zhayard <<a href='https://twitter.com/zeker_zhayard'>@Zeker_Zhayard</a>></p>\n";
|
||||
stream << "<p>Everyone who helped establish our branding!</p>\n";
|
||||
stream << "<p>And everyone else who <a href='https://github.com/PrismLauncher/PrismLauncher/graphs/contributors'>contributed</a>!</p>\n";
|
||||
stream
|
||||
<< "<p>And everyone else who <a href='https://github.com/PrismLauncher/PrismLauncher/graphs/contributors'>contributed</a>!</p>\n";
|
||||
stream << "<br />\n";
|
||||
|
||||
stream << "</center>\n";
|
||||
@ -124,9 +127,9 @@ QString getLicenseHtml()
|
||||
return output;
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace
|
||||
|
||||
AboutDialog::AboutDialog(QWidget *parent) : QDialog(parent), ui(new Ui::AboutDialog)
|
||||
AboutDialog::AboutDialog(QWidget* parent) : QDialog(parent), ui(new Ui::AboutDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
@ -148,7 +151,7 @@ AboutDialog::AboutDialog(QWidget *parent) : QDialog(parent), ui(new Ui::AboutDia
|
||||
ui->versionLabel->setText(BuildConfig.printableVersionString());
|
||||
|
||||
if (!BuildConfig.BUILD_PLATFORM.isEmpty())
|
||||
ui->platformLabel->setText(tr("Platform") +": " + BuildConfig.BUILD_PLATFORM);
|
||||
ui->platformLabel->setText(tr("Platform") + ": " + BuildConfig.BUILD_PLATFORM);
|
||||
else
|
||||
ui->platformLabel->setVisible(false);
|
||||
|
||||
@ -163,14 +166,14 @@ AboutDialog::AboutDialog(QWidget *parent) : QDialog(parent), ui(new Ui::AboutDia
|
||||
ui->buildDateLabel->setVisible(false);
|
||||
|
||||
if (!BuildConfig.VERSION_CHANNEL.isEmpty())
|
||||
ui->channelLabel->setText(tr("Channel") +": " + BuildConfig.VERSION_CHANNEL);
|
||||
ui->channelLabel->setText(tr("Channel") + ": " + BuildConfig.VERSION_CHANNEL);
|
||||
else
|
||||
ui->channelLabel->setVisible(false);
|
||||
|
||||
QString urlText("<html><head/><body><p><a href=\"%1\">%1</a></p></body></html>");
|
||||
ui->urlLabel->setText(urlText.arg(BuildConfig.LAUNCHER_GIT));
|
||||
|
||||
QString copyText("© 2022 %1");
|
||||
QString copyText("© 2022-2023 %1");
|
||||
ui->copyLabel->setText(copyText.arg(BuildConfig.LAUNCHER_COPYRIGHT));
|
||||
|
||||
connect(ui->closeButton, SIGNAL(clicked()), SLOT(close()));
|
||||
|
@ -15,26 +15,23 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QDialog>
|
||||
#include <net/NetJob.h>
|
||||
#include <QDialog>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
namespace Ui {
|
||||
class AboutDialog;
|
||||
}
|
||||
|
||||
class AboutDialog : public QDialog
|
||||
{
|
||||
class AboutDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit AboutDialog(QWidget *parent = 0);
|
||||
public:
|
||||
explicit AboutDialog(QWidget* parent = 0);
|
||||
~AboutDialog();
|
||||
|
||||
private:
|
||||
Ui::AboutDialog *ui;
|
||||
private:
|
||||
Ui::AboutDialog* ui;
|
||||
|
||||
NetJob::Ptr netJob;
|
||||
QByteArray dataSink;
|
||||
};
|
||||
|
||||
|
@ -313,7 +313,7 @@ bool BlockedModsDialog::checkValidPath(QString path)
|
||||
// efectivly compare two strings ignoring all separators and case
|
||||
auto laxCompare = [](QString fsfilename, QString metadataFilename) {
|
||||
// allowed character seperators
|
||||
QList<QChar> allowedSeperators = { '-', '+', '.' , '_'};
|
||||
QList<QChar> allowedSeperators = { '-', '+', '.', '_' };
|
||||
|
||||
// copy in lowercase
|
||||
auto fsName = fsfilename.toLower();
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
/*
|
||||
* PolyMC - Minecraft Launcher
|
||||
* Prism Launcher - Minecraft Launcher
|
||||
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
@ -107,8 +107,8 @@ CopyInstanceDialog::CopyInstanceDialog(InstancePtr original, QWidget* parent)
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
ui->symbolicLinksCheckbox->setIcon(style()->standardIcon(QStyle::SP_VistaShield));
|
||||
ui->symbolicLinksCheckbox->setToolTip(tr("Use symbolic links instead of copying files.") +
|
||||
"\n" + tr("On Windows, symbolic links may require admin permission to create."));
|
||||
ui->symbolicLinksCheckbox->setToolTip(tr("Use symbolic links instead of copying files.") + "\n" +
|
||||
tr("On Windows, symbolic links may require admin permission to create."));
|
||||
#endif
|
||||
|
||||
updateLinkOptions();
|
||||
|
@ -15,13 +15,15 @@
|
||||
|
||||
#include "CustomMessageBox.h"
|
||||
|
||||
namespace CustomMessageBox
|
||||
{
|
||||
QMessageBox *selectable(QWidget *parent, const QString &title, const QString &text,
|
||||
QMessageBox::Icon icon, QMessageBox::StandardButtons buttons,
|
||||
namespace CustomMessageBox {
|
||||
QMessageBox* selectable(QWidget* parent,
|
||||
const QString& title,
|
||||
const QString& text,
|
||||
QMessageBox::Icon icon,
|
||||
QMessageBox::StandardButtons buttons,
|
||||
QMessageBox::StandardButton defaultButton)
|
||||
{
|
||||
QMessageBox *messageBox = new QMessageBox(parent);
|
||||
QMessageBox* messageBox = new QMessageBox(parent);
|
||||
messageBox->setWindowTitle(title);
|
||||
messageBox->setText(text);
|
||||
messageBox->setStandardButtons(buttons);
|
||||
@ -32,4 +34,4 @@ QMessageBox *selectable(QWidget *parent, const QString &title, const QString &te
|
||||
|
||||
return messageBox;
|
||||
}
|
||||
}
|
||||
} // namespace CustomMessageBox
|
||||
|
@ -17,9 +17,10 @@
|
||||
|
||||
#include <QMessageBox>
|
||||
|
||||
namespace CustomMessageBox
|
||||
{
|
||||
QMessageBox *selectable(QWidget *parent, const QString &title, const QString &text,
|
||||
namespace CustomMessageBox {
|
||||
QMessageBox* selectable(QWidget* parent,
|
||||
const QString& title,
|
||||
const QString& text,
|
||||
QMessageBox::Icon icon = QMessageBox::NoIcon,
|
||||
QMessageBox::StandardButtons buttons = QMessageBox::Ok,
|
||||
QMessageBox::StandardButton defaultButton = QMessageBox::NoButton);
|
||||
|
@ -14,12 +14,11 @@
|
||||
*/
|
||||
|
||||
#include "EditAccountDialog.h"
|
||||
#include "ui_EditAccountDialog.h"
|
||||
#include <DesktopServices.h>
|
||||
#include <QUrl>
|
||||
#include "ui_EditAccountDialog.h"
|
||||
|
||||
EditAccountDialog::EditAccountDialog(const QString &text, QWidget *parent, int flags)
|
||||
: QDialog(parent), ui(new Ui::EditAccountDialog)
|
||||
EditAccountDialog::EditAccountDialog(const QString& text, QWidget* parent, int flags) : QDialog(parent), ui(new Ui::EditAccountDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
@ -35,12 +34,12 @@ EditAccountDialog::~EditAccountDialog()
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void EditAccountDialog::on_label_linkActivated(const QString &link)
|
||||
void EditAccountDialog::on_label_linkActivated(const QString& link)
|
||||
{
|
||||
DesktopServices::openUrl(QUrl(link));
|
||||
}
|
||||
|
||||
void EditAccountDialog::setUsername(const QString & user) const
|
||||
void EditAccountDialog::setUsername(const QString& user) const
|
||||
{
|
||||
ui->userTextBox->setText(user);
|
||||
}
|
||||
@ -50,7 +49,7 @@ QString EditAccountDialog::username() const
|
||||
return ui->userTextBox->text();
|
||||
}
|
||||
|
||||
void EditAccountDialog::setPassword(const QString & pass) const
|
||||
void EditAccountDialog::setPassword(const QString& pass) const
|
||||
{
|
||||
ui->passTextBox->setText(pass);
|
||||
}
|
||||
|
@ -17,28 +17,24 @@
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
namespace Ui {
|
||||
class EditAccountDialog;
|
||||
}
|
||||
|
||||
class EditAccountDialog : public QDialog
|
||||
{
|
||||
class EditAccountDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit EditAccountDialog(const QString &text = "", QWidget *parent = 0,
|
||||
int flags = UsernameField | PasswordField);
|
||||
public:
|
||||
explicit EditAccountDialog(const QString& text = "", QWidget* parent = 0, int flags = UsernameField | PasswordField);
|
||||
~EditAccountDialog();
|
||||
|
||||
void setUsername(const QString & user) const;
|
||||
void setPassword(const QString & pass) const;
|
||||
void setUsername(const QString& user) const;
|
||||
void setPassword(const QString& pass) const;
|
||||
|
||||
QString username() const;
|
||||
QString password() const;
|
||||
|
||||
enum Flags
|
||||
{
|
||||
enum Flags {
|
||||
NoFlags = 0,
|
||||
|
||||
//! Specifies that the dialog should have a username field.
|
||||
@ -48,9 +44,9 @@ public:
|
||||
PasswordField,
|
||||
};
|
||||
|
||||
private slots:
|
||||
void on_label_linkActivated(const QString &link);
|
||||
private slots:
|
||||
void on_label_linkActivated(const QString& link);
|
||||
|
||||
private:
|
||||
Ui::EditAccountDialog *ui;
|
||||
private:
|
||||
Ui::EditAccountDialog* ui;
|
||||
};
|
||||
|
@ -70,6 +70,8 @@ ExportInstanceDialog::ExportInstanceDialog(InstancePtr instance, QWidget* parent
|
||||
auto prefix = QDir(instance->instanceRoot()).relativeFilePath(instance->gameRoot());
|
||||
proxyModel->ignoreFilesWithPath().insert({ FS::PathCombine(prefix, "logs"), FS::PathCombine(prefix, "crash-reports") });
|
||||
proxyModel->ignoreFilesWithName().append({ ".DS_Store", "thumbs.db", "Thumbs.db" });
|
||||
proxyModel->ignoreFilesWithPath().insert(
|
||||
{ FS::PathCombine(prefix, ".cache"), FS::PathCombine(prefix, ".fabric"), FS::PathCombine(prefix, ".quilt") });
|
||||
loadPackIgnore();
|
||||
|
||||
ui->treeView->setModel(proxyModel);
|
||||
|
@ -61,7 +61,7 @@ ExportPackDialog::ExportPackDialog(InstancePtr instance, QWidget* parent, ModPla
|
||||
// use the game root - everything outside cannot be exported
|
||||
const QDir root(instance->gameRoot());
|
||||
proxy = new FileIgnoreProxy(instance->gameRoot(), this);
|
||||
proxy->ignoreFilesWithPath().insert({ "logs", "crash-reports" });
|
||||
proxy->ignoreFilesWithPath().insert({ "logs", "crash-reports", ".cache", ".fabric", ".quilt" });
|
||||
proxy->ignoreFilesWithName().append({ ".DS_Store", "thumbs.db", "Thumbs.db" });
|
||||
proxy->setSourceModel(model);
|
||||
|
||||
|
@ -13,9 +13,9 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <QFileDialog>
|
||||
#include <QKeyEvent>
|
||||
#include <QPushButton>
|
||||
#include <QFileDialog>
|
||||
|
||||
#include "Application.h"
|
||||
|
||||
@ -24,12 +24,11 @@
|
||||
|
||||
#include "ui/instanceview/InstanceDelegate.h"
|
||||
|
||||
#include <DesktopServices.h>
|
||||
#include "icons/IconList.h"
|
||||
#include "icons/IconUtils.h"
|
||||
#include <DesktopServices.h>
|
||||
|
||||
IconPickerDialog::IconPickerDialog(QWidget *parent)
|
||||
: QDialog(parent), ui(new Ui::IconPickerDialog)
|
||||
IconPickerDialog::IconPickerDialog(QWidget* parent) : QDialog(parent), ui(new Ui::IconPickerDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
setWindowModality(Qt::WindowModal);
|
||||
@ -69,31 +68,30 @@ IconPickerDialog::IconPickerDialog(QWidget *parent)
|
||||
|
||||
connect(contentsWidget, SIGNAL(doubleClicked(QModelIndex)), SLOT(activated(QModelIndex)));
|
||||
|
||||
connect(contentsWidget->selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)), SLOT(selectionChanged(QItemSelection, QItemSelection)));
|
||||
connect(contentsWidget->selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)),
|
||||
SLOT(selectionChanged(QItemSelection, QItemSelection)));
|
||||
|
||||
auto buttonFolder = ui->buttonBox->addButton(tr("Open Folder"), QDialogButtonBox::ResetRole);
|
||||
connect(buttonFolder, &QPushButton::clicked, this, &IconPickerDialog::openFolder);
|
||||
}
|
||||
|
||||
bool IconPickerDialog::eventFilter(QObject *obj, QEvent *evt)
|
||||
bool IconPickerDialog::eventFilter(QObject* obj, QEvent* evt)
|
||||
{
|
||||
if (obj != ui->iconView)
|
||||
return QDialog::eventFilter(obj, evt);
|
||||
if (evt->type() != QEvent::KeyPress)
|
||||
{
|
||||
if (evt->type() != QEvent::KeyPress) {
|
||||
return QDialog::eventFilter(obj, evt);
|
||||
}
|
||||
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(evt);
|
||||
switch (keyEvent->key())
|
||||
{
|
||||
case Qt::Key_Delete:
|
||||
removeSelectedIcon();
|
||||
return true;
|
||||
case Qt::Key_Plus:
|
||||
addNewIcon();
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(evt);
|
||||
switch (keyEvent->key()) {
|
||||
case Qt::Key_Delete:
|
||||
removeSelectedIcon();
|
||||
return true;
|
||||
case Qt::Key_Plus:
|
||||
addNewIcon();
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return QDialog::eventFilter(obj, evt);
|
||||
}
|
||||
@ -142,8 +140,7 @@ int IconPickerDialog::execWithSelection(QString selection)
|
||||
|
||||
int index_nr = list->getIconIndex(selection);
|
||||
auto model_index = list->index(index_nr);
|
||||
contentsWidget->selectionModel()->select(
|
||||
model_index, QItemSelectionModel::Current | QItemSelectionModel::Select);
|
||||
contentsWidget->selectionModel()->select(model_index, QItemSelectionModel::Current | QItemSelectionModel::Select);
|
||||
|
||||
QMetaObject::invokeMethod(this, "delayed_scroll", Qt::QueuedConnection, Q_ARG(QModelIndex, model_index));
|
||||
return QDialog::exec();
|
||||
|
@ -17,30 +17,27 @@
|
||||
#include <QDialog>
|
||||
#include <QItemSelection>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
namespace Ui {
|
||||
class IconPickerDialog;
|
||||
}
|
||||
|
||||
class IconPickerDialog : public QDialog
|
||||
{
|
||||
class IconPickerDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit IconPickerDialog(QWidget *parent = 0);
|
||||
public:
|
||||
explicit IconPickerDialog(QWidget* parent = 0);
|
||||
~IconPickerDialog();
|
||||
int execWithSelection(QString selection);
|
||||
QString selectedIconKey;
|
||||
|
||||
protected:
|
||||
virtual bool eventFilter(QObject *, QEvent *);
|
||||
protected:
|
||||
virtual bool eventFilter(QObject*, QEvent*);
|
||||
|
||||
private:
|
||||
Ui::IconPickerDialog *ui;
|
||||
QPushButton *buttonRemove;
|
||||
private:
|
||||
Ui::IconPickerDialog* ui;
|
||||
QPushButton* buttonRemove;
|
||||
|
||||
private
|
||||
slots:
|
||||
private slots:
|
||||
void selectionChanged(QItemSelection, QItemSelection);
|
||||
void activated(QModelIndex);
|
||||
void delayed_scroll(QModelIndex);
|
||||
|
@ -17,7 +17,7 @@ class ImportResourceDialog : public QDialog {
|
||||
explicit ImportResourceDialog(QString file_path, PackedResourceType type, QWidget* parent = nullptr);
|
||||
~ImportResourceDialog() override;
|
||||
QString selectedInstanceKey;
|
||||
|
||||
|
||||
private:
|
||||
Ui::ImportResourceDialog* ui;
|
||||
PackedResourceType m_resource_type;
|
||||
|
@ -20,7 +20,7 @@
|
||||
|
||||
#include <QtWidgets/QPushButton>
|
||||
|
||||
LoginDialog::LoginDialog(QWidget *parent) : QDialog(parent), ui(new Ui::LoginDialog)
|
||||
LoginDialog::LoginDialog(QWidget* parent) : QDialog(parent), ui(new Ui::LoginDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->progressBar->setVisible(false);
|
||||
@ -59,27 +59,24 @@ void LoginDialog::setUserInputsEnabled(bool enable)
|
||||
}
|
||||
|
||||
// Enable the OK button only when both textboxes contain something.
|
||||
void LoginDialog::on_userTextBox_textEdited(const QString &newText)
|
||||
void LoginDialog::on_userTextBox_textEdited(const QString& newText)
|
||||
{
|
||||
ui->buttonBox->button(QDialogButtonBox::Ok)
|
||||
->setEnabled(!newText.isEmpty() && !ui->passTextBox->text().isEmpty());
|
||||
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!newText.isEmpty() && !ui->passTextBox->text().isEmpty());
|
||||
}
|
||||
void LoginDialog::on_passTextBox_textEdited(const QString &newText)
|
||||
void LoginDialog::on_passTextBox_textEdited(const QString& newText)
|
||||
{
|
||||
ui->buttonBox->button(QDialogButtonBox::Ok)
|
||||
->setEnabled(!newText.isEmpty() && !ui->userTextBox->text().isEmpty());
|
||||
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!newText.isEmpty() && !ui->userTextBox->text().isEmpty());
|
||||
}
|
||||
|
||||
void LoginDialog::onTaskFailed(const QString &reason)
|
||||
void LoginDialog::onTaskFailed(const QString& reason)
|
||||
{
|
||||
// Set message
|
||||
auto lines = reason.split('\n');
|
||||
QString processed;
|
||||
for(auto line: lines) {
|
||||
if(line.size()) {
|
||||
for (auto line : lines) {
|
||||
if (line.size()) {
|
||||
processed += "<font color='red'>" + line + "</font><br />";
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
processed += "<br />";
|
||||
}
|
||||
}
|
||||
@ -95,7 +92,7 @@ void LoginDialog::onTaskSucceeded()
|
||||
QDialog::accept();
|
||||
}
|
||||
|
||||
void LoginDialog::onTaskStatus(const QString &status)
|
||||
void LoginDialog::onTaskStatus(const QString& status)
|
||||
{
|
||||
ui->label->setText(status);
|
||||
}
|
||||
@ -107,12 +104,11 @@ void LoginDialog::onTaskProgress(qint64 current, qint64 total)
|
||||
}
|
||||
|
||||
// Public interface
|
||||
MinecraftAccountPtr LoginDialog::newAccount(QWidget *parent, QString msg)
|
||||
MinecraftAccountPtr LoginDialog::newAccount(QWidget* parent, QString msg)
|
||||
{
|
||||
LoginDialog dlg(parent);
|
||||
dlg.ui->label->setText(msg);
|
||||
if (dlg.exec() == QDialog::Accepted)
|
||||
{
|
||||
if (dlg.exec() == QDialog::Accepted) {
|
||||
return dlg.m_account;
|
||||
}
|
||||
return nullptr;
|
||||
|
@ -15,45 +15,42 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QtWidgets/QDialog>
|
||||
#include <QtCore/QEventLoop>
|
||||
#include <QtWidgets/QDialog>
|
||||
|
||||
#include "minecraft/auth/MinecraftAccount.h"
|
||||
#include "tasks/Task.h"
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
namespace Ui {
|
||||
class LoginDialog;
|
||||
}
|
||||
|
||||
class LoginDialog : public QDialog
|
||||
{
|
||||
class LoginDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
public:
|
||||
~LoginDialog();
|
||||
|
||||
static MinecraftAccountPtr newAccount(QWidget *parent, QString message);
|
||||
static MinecraftAccountPtr newAccount(QWidget* parent, QString message);
|
||||
|
||||
private:
|
||||
explicit LoginDialog(QWidget *parent = 0);
|
||||
private:
|
||||
explicit LoginDialog(QWidget* parent = 0);
|
||||
|
||||
void setUserInputsEnabled(bool enable);
|
||||
|
||||
protected
|
||||
slots:
|
||||
protected slots:
|
||||
void accept();
|
||||
|
||||
void onTaskFailed(const QString &reason);
|
||||
void onTaskFailed(const QString& reason);
|
||||
void onTaskSucceeded();
|
||||
void onTaskStatus(const QString &status);
|
||||
void onTaskStatus(const QString& status);
|
||||
void onTaskProgress(qint64 current, qint64 total);
|
||||
|
||||
void on_userTextBox_textEdited(const QString &newText);
|
||||
void on_passTextBox_textEdited(const QString &newText);
|
||||
void on_userTextBox_textEdited(const QString& newText);
|
||||
void on_passTextBox_textEdited(const QString& newText);
|
||||
|
||||
private:
|
||||
Ui::LoginDialog *ui;
|
||||
private:
|
||||
Ui::LoginDialog* ui;
|
||||
MinecraftAccountPtr m_account;
|
||||
Task::Ptr m_loginTask;
|
||||
};
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
/*
|
||||
* PolyMC - Minecraft Launcher
|
||||
* Prism Launcher - Minecraft Launcher
|
||||
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
@ -39,12 +39,12 @@
|
||||
#include "DesktopServices.h"
|
||||
#include "minecraft/auth/AccountTask.h"
|
||||
|
||||
#include <QtWidgets/QPushButton>
|
||||
#include <QUrl>
|
||||
#include <QApplication>
|
||||
#include <QClipboard>
|
||||
#include <QUrl>
|
||||
#include <QtWidgets/QPushButton>
|
||||
|
||||
MSALoginDialog::MSALoginDialog(QWidget *parent) : QDialog(parent), ui(new Ui::MSALoginDialog)
|
||||
MSALoginDialog::MSALoginDialog(QWidget* parent) : QDialog(parent), ui(new Ui::MSALoginDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->progressBar->setVisible(false);
|
||||
@ -55,7 +55,8 @@ MSALoginDialog::MSALoginDialog(QWidget *parent) : QDialog(parent), ui(new Ui::MS
|
||||
connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
|
||||
}
|
||||
|
||||
int MSALoginDialog::exec() {
|
||||
int MSALoginDialog::exec()
|
||||
{
|
||||
setUserInputsEnabled(false);
|
||||
ui->progressBar->setVisible(true);
|
||||
|
||||
@ -74,24 +75,24 @@ int MSALoginDialog::exec() {
|
||||
return QDialog::exec();
|
||||
}
|
||||
|
||||
|
||||
MSALoginDialog::~MSALoginDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void MSALoginDialog::externalLoginTick() {
|
||||
void MSALoginDialog::externalLoginTick()
|
||||
{
|
||||
m_externalLoginElapsed++;
|
||||
ui->progressBar->setValue(m_externalLoginElapsed);
|
||||
ui->progressBar->repaint();
|
||||
|
||||
if(m_externalLoginElapsed >= m_externalLoginTimeout) {
|
||||
if (m_externalLoginElapsed >= m_externalLoginTimeout) {
|
||||
m_externalLoginTimer.stop();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MSALoginDialog::showVerificationUriAndCode(const QUrl& uri, const QString& code, int expiresIn) {
|
||||
void MSALoginDialog::showVerificationUriAndCode(const QUrl& uri, const QString& code, int expiresIn)
|
||||
{
|
||||
m_externalLoginElapsed = 0;
|
||||
m_externalLoginTimeout = expiresIn;
|
||||
|
||||
@ -104,7 +105,8 @@ void MSALoginDialog::showVerificationUriAndCode(const QUrl& uri, const QString&
|
||||
|
||||
QString urlString = uri.toString();
|
||||
QString linkString = QString("<a href=\"%1\">%2</a>").arg(urlString, urlString);
|
||||
ui->label->setText(tr("<p>Please open up %1 in a browser and put in the code <b>%2</b> to proceed with login.</p>").arg(linkString, code));
|
||||
ui->label->setText(
|
||||
tr("<p>Please open up %1 in a browser and put in the code <b>%2</b> to proceed with login.</p>").arg(linkString, code));
|
||||
ui->actionButton->setVisible(true);
|
||||
connect(ui->actionButton, &QPushButton::clicked, [=]() {
|
||||
DesktopServices::openUrl(uri);
|
||||
@ -113,7 +115,8 @@ void MSALoginDialog::showVerificationUriAndCode(const QUrl& uri, const QString&
|
||||
});
|
||||
}
|
||||
|
||||
void MSALoginDialog::hideVerificationUriAndCode() {
|
||||
void MSALoginDialog::hideVerificationUriAndCode()
|
||||
{
|
||||
m_externalLoginTimer.stop();
|
||||
ui->actionButton->setVisible(false);
|
||||
}
|
||||
@ -123,16 +126,15 @@ void MSALoginDialog::setUserInputsEnabled(bool enable)
|
||||
ui->buttonBox->setEnabled(enable);
|
||||
}
|
||||
|
||||
void MSALoginDialog::onTaskFailed(const QString &reason)
|
||||
void MSALoginDialog::onTaskFailed(const QString& reason)
|
||||
{
|
||||
// Set message
|
||||
auto lines = reason.split('\n');
|
||||
QString processed;
|
||||
for(auto line: lines) {
|
||||
if(line.size()) {
|
||||
for (auto line : lines) {
|
||||
if (line.size()) {
|
||||
processed += "<font color='red'>" + line + "</font><br />";
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
processed += "<br />";
|
||||
}
|
||||
}
|
||||
@ -149,7 +151,7 @@ void MSALoginDialog::onTaskSucceeded()
|
||||
QDialog::accept();
|
||||
}
|
||||
|
||||
void MSALoginDialog::onTaskStatus(const QString &status)
|
||||
void MSALoginDialog::onTaskStatus(const QString& status)
|
||||
{
|
||||
ui->label->setText(status);
|
||||
}
|
||||
@ -161,12 +163,11 @@ void MSALoginDialog::onTaskProgress(qint64 current, qint64 total)
|
||||
}
|
||||
|
||||
// Public interface
|
||||
MinecraftAccountPtr MSALoginDialog::newAccount(QWidget *parent, QString msg)
|
||||
MinecraftAccountPtr MSALoginDialog::newAccount(QWidget* parent, QString msg)
|
||||
{
|
||||
MSALoginDialog dlg(parent);
|
||||
dlg.ui->label->setText(msg);
|
||||
if (dlg.exec() == QDialog::Accepted)
|
||||
{
|
||||
if (dlg.exec() == QDialog::Accepted) {
|
||||
return dlg.m_account;
|
||||
}
|
||||
return nullptr;
|
||||
|
@ -15,49 +15,45 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QtWidgets/QDialog>
|
||||
#include <QtCore/QEventLoop>
|
||||
#include <QTimer>
|
||||
#include <QtCore/QEventLoop>
|
||||
#include <QtWidgets/QDialog>
|
||||
|
||||
#include "minecraft/auth/MinecraftAccount.h"
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
namespace Ui {
|
||||
class MSALoginDialog;
|
||||
}
|
||||
|
||||
class MSALoginDialog : public QDialog
|
||||
{
|
||||
class MSALoginDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
public:
|
||||
~MSALoginDialog();
|
||||
|
||||
static MinecraftAccountPtr newAccount(QWidget *parent, QString message);
|
||||
static MinecraftAccountPtr newAccount(QWidget* parent, QString message);
|
||||
int exec() override;
|
||||
|
||||
private:
|
||||
explicit MSALoginDialog(QWidget *parent = 0);
|
||||
private:
|
||||
explicit MSALoginDialog(QWidget* parent = 0);
|
||||
|
||||
void setUserInputsEnabled(bool enable);
|
||||
|
||||
protected
|
||||
slots:
|
||||
void onTaskFailed(const QString &reason);
|
||||
protected slots:
|
||||
void onTaskFailed(const QString& reason);
|
||||
void onTaskSucceeded();
|
||||
void onTaskStatus(const QString &status);
|
||||
void onTaskStatus(const QString& status);
|
||||
void onTaskProgress(qint64 current, qint64 total);
|
||||
void showVerificationUriAndCode(const QUrl &uri, const QString &code, int expiresIn);
|
||||
void showVerificationUriAndCode(const QUrl& uri, const QString& code, int expiresIn);
|
||||
void hideVerificationUriAndCode();
|
||||
|
||||
void externalLoginTick();
|
||||
|
||||
private:
|
||||
Ui::MSALoginDialog *ui;
|
||||
private:
|
||||
Ui::MSALoginDialog* ui;
|
||||
MinecraftAccountPtr m_account;
|
||||
shared_qobject_ptr<AccountTask> m_loginTask;
|
||||
QTimer m_externalLoginTimer;
|
||||
int m_externalLoginElapsed = 0;
|
||||
int m_externalLoginTimeout = 0;
|
||||
};
|
||||
|
||||
|
@ -89,15 +89,17 @@ void ModUpdateDialog::checkCandidates()
|
||||
|
||||
if (!m_modrinth_to_update.empty()) {
|
||||
m_modrinth_check_task.reset(new ModrinthCheckUpdate(m_modrinth_to_update, versions, loaders, m_mod_model));
|
||||
connect(m_modrinth_check_task.get(), &CheckUpdateTask::checkFailed, this,
|
||||
[this](Mod* mod, QString reason, QUrl recover_url) { m_failed_check_update.append({mod, reason, recover_url}); });
|
||||
connect(m_modrinth_check_task.get(), &CheckUpdateTask::checkFailed, this, [this](Mod* mod, QString reason, QUrl recover_url) {
|
||||
m_failed_check_update.append({ mod, reason, recover_url });
|
||||
});
|
||||
check_task.addTask(m_modrinth_check_task);
|
||||
}
|
||||
|
||||
if (!m_flame_to_update.empty()) {
|
||||
m_flame_check_task.reset(new FlameCheckUpdate(m_flame_to_update, versions, loaders, m_mod_model));
|
||||
connect(m_flame_check_task.get(), &CheckUpdateTask::checkFailed, this,
|
||||
[this](Mod* mod, QString reason, QUrl recover_url) { m_failed_check_update.append({mod, reason, recover_url}); });
|
||||
connect(m_flame_check_task.get(), &CheckUpdateTask::checkFailed, this, [this](Mod* mod, QString reason, QUrl recover_url) {
|
||||
m_failed_check_update.append({ mod, reason, recover_url });
|
||||
});
|
||||
check_task.addTask(m_flame_check_task);
|
||||
}
|
||||
|
||||
@ -162,7 +164,7 @@ void ModUpdateDialog::checkCandidates()
|
||||
if (!recover_url.isEmpty())
|
||||
//: %1 is the link to download it manually
|
||||
text += tr("Possible solution: Getting the latest version manually:<br>%1<br>")
|
||||
.arg(QString("<a href='%1'>%1</a>").arg(recover_url.toString()));
|
||||
.arg(QString("<a href='%1'>%1</a>").arg(recover_url.toString()));
|
||||
text += "<br>";
|
||||
}
|
||||
|
||||
@ -342,7 +344,7 @@ void ModUpdateDialog::onMetadataFailed(Mod* mod, bool try_others, ModPlatform::R
|
||||
} else {
|
||||
QString reason{ tr("Couldn't find a valid version on the selected mod provider(s)") };
|
||||
|
||||
m_failed_metadata.append({mod, reason});
|
||||
m_failed_metadata.append({ mod, reason });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,9 @@ class ModUpdateDialog final : public ReviewMessageBox {
|
||||
|
||||
private slots:
|
||||
void onMetadataEnsured(Mod*);
|
||||
void onMetadataFailed(Mod*, bool try_others = false, ModPlatform::ResourceProvider first_choice = ModPlatform::ResourceProvider::MODRINTH);
|
||||
void onMetadataFailed(Mod*,
|
||||
bool try_others = false,
|
||||
ModPlatform::ResourceProvider first_choice = ModPlatform::ResourceProvider::MODRINTH);
|
||||
|
||||
private:
|
||||
QWidget* m_parent;
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
/*
|
||||
* PolyMC - Minecraft Launcher
|
||||
* Prism Launcher - Minecraft Launcher
|
||||
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
@ -33,28 +33,28 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "Application.h"
|
||||
#include "NewComponentDialog.h"
|
||||
#include "Application.h"
|
||||
#include "ui_NewComponentDialog.h"
|
||||
|
||||
#include <BaseVersion.h>
|
||||
#include <InstanceList.h>
|
||||
#include <icons/IconList.h>
|
||||
#include <tasks/Task.h>
|
||||
#include <InstanceList.h>
|
||||
|
||||
#include "VersionSelectDialog.h"
|
||||
#include "ProgressDialog.h"
|
||||
#include "IconPickerDialog.h"
|
||||
#include "ProgressDialog.h"
|
||||
#include "VersionSelectDialog.h"
|
||||
|
||||
#include <QFileDialog>
|
||||
#include <QLayout>
|
||||
#include <QPushButton>
|
||||
#include <QFileDialog>
|
||||
#include <QValidator>
|
||||
|
||||
#include <meta/Index.h>
|
||||
#include <meta/VersionList.h>
|
||||
|
||||
NewComponentDialog::NewComponentDialog(const QString & initialName, const QString & initialUid, QWidget *parent)
|
||||
NewComponentDialog::NewComponentDialog(const QString& initialName, const QString& initialUid, QWidget* parent)
|
||||
: QDialog(parent), ui(new Ui::NewComponentDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
@ -81,12 +81,9 @@ void NewComponentDialog::updateDialogState()
|
||||
{
|
||||
auto protoUid = ui->nameTextBox->text().toLower();
|
||||
protoUid.remove(QRegularExpression("[^a-z]"));
|
||||
if(protoUid.isEmpty())
|
||||
{
|
||||
if (protoUid.isEmpty()) {
|
||||
ui->uidTextBox->setPlaceholderText(originalPlaceholderText);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
QString suggestedUid = "org.multimc.custom." + protoUid;
|
||||
ui->uidTextBox->setPlaceholderText(suggestedUid);
|
||||
}
|
||||
@ -97,8 +94,7 @@ void NewComponentDialog::updateDialogState()
|
||||
QString NewComponentDialog::name() const
|
||||
{
|
||||
auto result = ui->nameTextBox->text();
|
||||
if(result.size())
|
||||
{
|
||||
if (result.size()) {
|
||||
return result.trimmed();
|
||||
}
|
||||
return QString();
|
||||
@ -107,13 +103,11 @@ QString NewComponentDialog::name() const
|
||||
QString NewComponentDialog::uid() const
|
||||
{
|
||||
auto result = ui->uidTextBox->text();
|
||||
if(result.size())
|
||||
{
|
||||
if (result.size()) {
|
||||
return result.trimmed();
|
||||
}
|
||||
result = ui->uidTextBox->placeholderText();
|
||||
if(result.size() && result != originalPlaceholderText)
|
||||
{
|
||||
if (result.size() && result != originalPlaceholderText) {
|
||||
return result.trimmed();
|
||||
}
|
||||
return QString();
|
||||
|
@ -20,28 +20,26 @@
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
namespace Ui {
|
||||
class NewComponentDialog;
|
||||
}
|
||||
|
||||
class NewComponentDialog : public QDialog
|
||||
{
|
||||
class NewComponentDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit NewComponentDialog(const QString & initialName = QString(), const QString & initialUid = QString(), QWidget *parent = 0);
|
||||
public:
|
||||
explicit NewComponentDialog(const QString& initialName = QString(), const QString& initialUid = QString(), QWidget* parent = 0);
|
||||
virtual ~NewComponentDialog();
|
||||
void setBlacklist(QStringList badUids);
|
||||
|
||||
QString name() const;
|
||||
QString uid() const;
|
||||
|
||||
private slots:
|
||||
private slots:
|
||||
void updateDialogState();
|
||||
|
||||
private:
|
||||
Ui::NewComponentDialog *ui;
|
||||
private:
|
||||
Ui::NewComponentDialog* ui;
|
||||
|
||||
QString originalPlaceholderText;
|
||||
QStringList uidBlacklist;
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
/*
|
||||
* PolyMC - Minecraft Launcher
|
||||
* Prism Launcher - Minecraft Launcher
|
||||
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
@ -33,38 +33,37 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "Application.h"
|
||||
#include "NewInstanceDialog.h"
|
||||
#include "Application.h"
|
||||
#include "ui/pages/modplatform/import_ftb/ImportFTBPage.h"
|
||||
#include "ui_NewInstanceDialog.h"
|
||||
|
||||
#include <BaseVersion.h>
|
||||
#include <InstanceList.h>
|
||||
#include <icons/IconList.h>
|
||||
#include <tasks/Task.h>
|
||||
#include <InstanceList.h>
|
||||
|
||||
#include "VersionSelectDialog.h"
|
||||
#include "ProgressDialog.h"
|
||||
#include "IconPickerDialog.h"
|
||||
#include "ProgressDialog.h"
|
||||
#include "VersionSelectDialog.h"
|
||||
|
||||
#include <QDialogButtonBox>
|
||||
#include <QFileDialog>
|
||||
#include <QLayout>
|
||||
#include <QPushButton>
|
||||
#include <QFileDialog>
|
||||
#include <QValidator>
|
||||
#include <QDialogButtonBox>
|
||||
#include <utility>
|
||||
|
||||
#include "ui/widgets/PageContainer.h"
|
||||
#include "ui/pages/modplatform/CustomPage.h"
|
||||
#include "ui/pages/modplatform/atlauncher/AtlPage.h"
|
||||
#include "ui/pages/modplatform/legacy_ftb/Page.h"
|
||||
#include "ui/pages/modplatform/flame/FlamePage.h"
|
||||
#include "ui/pages/modplatform/ImportPage.h"
|
||||
#include "ui/pages/modplatform/atlauncher/AtlPage.h"
|
||||
#include "ui/pages/modplatform/flame/FlamePage.h"
|
||||
#include "ui/pages/modplatform/legacy_ftb/Page.h"
|
||||
#include "ui/pages/modplatform/modrinth/ModrinthPage.h"
|
||||
#include "ui/pages/modplatform/technic/TechnicPage.h"
|
||||
#include "ui/widgets/PageContainer.h"
|
||||
|
||||
|
||||
|
||||
NewInstanceDialog::NewInstanceDialog(const QString & initialGroup, const QString & url, QWidget *parent)
|
||||
NewInstanceDialog::NewInstanceDialog(const QString& initialGroup, const QString& url, QWidget* parent)
|
||||
: QDialog(parent), ui(new Ui::NewInstanceDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
@ -88,15 +87,14 @@ NewInstanceDialog::NewInstanceDialog(const QString & initialGroup, const QString
|
||||
groupList.push_front("");
|
||||
ui->groupBox->addItems(groupList);
|
||||
int index = groupList.indexOf(initialGroup);
|
||||
if(index == -1)
|
||||
{
|
||||
if (index == -1) {
|
||||
index = 0;
|
||||
}
|
||||
ui->groupBox->setCurrentIndex(index);
|
||||
ui->groupBox->lineEdit()->setPlaceholderText(tr("No group"));
|
||||
|
||||
|
||||
// NOTE: m_buttons must be initialized before PageContainer, because it indirectly accesses m_buttons through setSuggestedPack! Do not move this below.
|
||||
// NOTE: m_buttons must be initialized before PageContainer, because it indirectly accesses m_buttons through setSuggestedPack! Do not
|
||||
// move this below.
|
||||
m_buttons = new QDialogButtonBox(QDialogButtonBox::Help | QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
|
||||
m_container = new PageContainer(this, {}, this);
|
||||
@ -123,8 +121,7 @@ NewInstanceDialog::NewInstanceDialog(const QString & initialGroup, const QString
|
||||
HelpButton->setAutoDefault(false);
|
||||
connect(HelpButton, &QPushButton::clicked, m_container, &PageContainer::help);
|
||||
|
||||
if(!url.isEmpty())
|
||||
{
|
||||
if (!url.isEmpty()) {
|
||||
QUrl actualUrl(url);
|
||||
m_container->selectPage("import");
|
||||
importPage->setUrl(url);
|
||||
@ -156,9 +153,9 @@ void NewInstanceDialog::accept()
|
||||
QDialog::accept();
|
||||
}
|
||||
|
||||
QList<BasePage *> NewInstanceDialog::getPages()
|
||||
QList<BasePage*> NewInstanceDialog::getPages()
|
||||
{
|
||||
QList<BasePage *> pages;
|
||||
QList<BasePage*> pages;
|
||||
|
||||
importPage = new ImportPage(this);
|
||||
|
||||
@ -168,6 +165,7 @@ QList<BasePage *> NewInstanceDialog::getPages()
|
||||
if (APPLICATION->capabilities() & Application::SupportsFlame)
|
||||
pages.append(new FlamePage(this));
|
||||
pages.append(new LegacyFTB::Page(this));
|
||||
pages.append(new FTBImportAPP::ImportFTBPage(this));
|
||||
pages.append(new ModrinthPage(this));
|
||||
pages.append(new TechnicPage(this));
|
||||
|
||||
@ -216,17 +214,17 @@ void NewInstanceDialog::setSuggestedPack(const QString& name, QString version, I
|
||||
m_buttons->button(QDialogButtonBox::Ok)->setEnabled(allowOK);
|
||||
}
|
||||
|
||||
void NewInstanceDialog::setSuggestedIconFromFile(const QString &path, const QString &name)
|
||||
void NewInstanceDialog::setSuggestedIconFromFile(const QString& path, const QString& name)
|
||||
{
|
||||
importIcon = true;
|
||||
importIconPath = path;
|
||||
importIconName = name;
|
||||
|
||||
//Hmm, for some reason they can be to small
|
||||
// Hmm, for some reason they can be to small
|
||||
ui->iconButton->setIcon(QIcon(path));
|
||||
}
|
||||
|
||||
void NewInstanceDialog::setSuggestedIcon(const QString &key)
|
||||
void NewInstanceDialog::setSuggestedIcon(const QString& key)
|
||||
{
|
||||
auto icon = APPLICATION->icons()->getIcon(key);
|
||||
importIcon = false;
|
||||
@ -234,9 +232,9 @@ void NewInstanceDialog::setSuggestedIcon(const QString &key)
|
||||
ui->iconButton->setIcon(icon);
|
||||
}
|
||||
|
||||
InstanceTask * NewInstanceDialog::extractTask()
|
||||
InstanceTask* NewInstanceDialog::extractTask()
|
||||
{
|
||||
InstanceTask * extracted = creationTask.get();
|
||||
InstanceTask* extracted = creationTask.get();
|
||||
creationTask.release();
|
||||
|
||||
InstanceName inst_name(ui->instNameTextBox->placeholderText().trimmed(), importVersion);
|
||||
@ -252,8 +250,7 @@ void NewInstanceDialog::updateDialogState()
|
||||
{
|
||||
auto allowOK = creationTask && !instName().isEmpty();
|
||||
auto OkButton = m_buttons->button(QDialogButtonBox::Ok);
|
||||
if(OkButton->isEnabled() != allowOK)
|
||||
{
|
||||
if (OkButton->isEnabled() != allowOK) {
|
||||
OkButton->setEnabled(allowOK);
|
||||
}
|
||||
}
|
||||
@ -261,13 +258,11 @@ void NewInstanceDialog::updateDialogState()
|
||||
QString NewInstanceDialog::instName() const
|
||||
{
|
||||
auto result = ui->instNameTextBox->text().trimmed();
|
||||
if(result.size())
|
||||
{
|
||||
if (result.size()) {
|
||||
return result;
|
||||
}
|
||||
result = ui->instNameTextBox->placeholderText().trimmed();
|
||||
if(result.size())
|
||||
{
|
||||
if (result.size()) {
|
||||
return result;
|
||||
}
|
||||
return QString();
|
||||
@ -284,26 +279,25 @@ QString NewInstanceDialog::iconKey() const
|
||||
|
||||
void NewInstanceDialog::on_iconButton_clicked()
|
||||
{
|
||||
importIconNow(); //so the user can switch back
|
||||
importIconNow(); // so the user can switch back
|
||||
IconPickerDialog dlg(this);
|
||||
dlg.execWithSelection(InstIconKey);
|
||||
|
||||
if (dlg.result() == QDialog::Accepted)
|
||||
{
|
||||
if (dlg.result() == QDialog::Accepted) {
|
||||
InstIconKey = dlg.selectedIconKey;
|
||||
ui->iconButton->setIcon(APPLICATION->icons()->getIcon(InstIconKey));
|
||||
importIcon = false;
|
||||
}
|
||||
}
|
||||
|
||||
void NewInstanceDialog::on_instNameTextBox_textChanged(const QString &arg1)
|
||||
void NewInstanceDialog::on_instNameTextBox_textChanged(const QString& arg1)
|
||||
{
|
||||
updateDialogState();
|
||||
}
|
||||
|
||||
void NewInstanceDialog::importIconNow()
|
||||
{
|
||||
if(importIcon) {
|
||||
if (importIcon) {
|
||||
APPLICATION->icons()->installIcon(importIconPath, importIconName);
|
||||
InstIconKey = importIconName;
|
||||
importIcon = false;
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
/*
|
||||
* PolyMC - Minecraft Launcher
|
||||
* Prism Launcher - Minecraft Launcher
|
||||
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
@ -37,11 +37,10 @@
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
#include "ui/pages/BasePageProvider.h"
|
||||
#include "InstanceTask.h"
|
||||
#include "ui/pages/BasePageProvider.h"
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
namespace Ui {
|
||||
class NewInstanceDialog;
|
||||
}
|
||||
|
||||
@ -50,45 +49,44 @@ class QDialogButtonBox;
|
||||
class ImportPage;
|
||||
class FlamePage;
|
||||
|
||||
class NewInstanceDialog : public QDialog, public BasePageProvider
|
||||
{
|
||||
class NewInstanceDialog : public QDialog, public BasePageProvider {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit NewInstanceDialog(const QString & initialGroup, const QString & url = QString(), QWidget *parent = 0);
|
||||
public:
|
||||
explicit NewInstanceDialog(const QString& initialGroup, const QString& url = QString(), QWidget* parent = 0);
|
||||
~NewInstanceDialog();
|
||||
|
||||
void updateDialogState();
|
||||
|
||||
void setSuggestedPack(const QString& name = QString(), InstanceTask * task = nullptr);
|
||||
void setSuggestedPack(const QString& name, QString version, InstanceTask * task = nullptr);
|
||||
void setSuggestedIconFromFile(const QString &path, const QString &name);
|
||||
void setSuggestedIcon(const QString &key);
|
||||
void setSuggestedPack(const QString& name = QString(), InstanceTask* task = nullptr);
|
||||
void setSuggestedPack(const QString& name, QString version, InstanceTask* task = nullptr);
|
||||
void setSuggestedIconFromFile(const QString& path, const QString& name);
|
||||
void setSuggestedIcon(const QString& key);
|
||||
|
||||
InstanceTask * extractTask();
|
||||
InstanceTask* extractTask();
|
||||
|
||||
QString dialogTitle() override;
|
||||
QList<BasePage *> getPages() override;
|
||||
QList<BasePage*> getPages() override;
|
||||
|
||||
QString instName() const;
|
||||
QString instGroup() const;
|
||||
QString iconKey() const;
|
||||
|
||||
public slots:
|
||||
public slots:
|
||||
void accept() override;
|
||||
void reject() override;
|
||||
|
||||
private slots:
|
||||
private slots:
|
||||
void on_iconButton_clicked();
|
||||
void on_instNameTextBox_textChanged(const QString &arg1);
|
||||
void on_instNameTextBox_textChanged(const QString& arg1);
|
||||
|
||||
private:
|
||||
Ui::NewInstanceDialog *ui = nullptr;
|
||||
PageContainer * m_container = nullptr;
|
||||
QDialogButtonBox * m_buttons = nullptr;
|
||||
private:
|
||||
Ui::NewInstanceDialog* ui = nullptr;
|
||||
PageContainer* m_container = nullptr;
|
||||
QDialogButtonBox* m_buttons = nullptr;
|
||||
|
||||
QString InstIconKey;
|
||||
ImportPage *importPage = nullptr;
|
||||
ImportPage* importPage = nullptr;
|
||||
std::unique_ptr<InstanceTask> creationTask;
|
||||
|
||||
bool importIcon = false;
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
#include <QtWidgets/QPushButton>
|
||||
|
||||
OfflineLoginDialog::OfflineLoginDialog(QWidget *parent) : QDialog(parent), ui(new Ui::OfflineLoginDialog)
|
||||
OfflineLoginDialog::OfflineLoginDialog(QWidget* parent) : QDialog(parent), ui(new Ui::OfflineLoginDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->progressBar->setVisible(false);
|
||||
@ -52,22 +52,20 @@ void OfflineLoginDialog::on_allowLongUsernames_stateChanged(int value)
|
||||
}
|
||||
|
||||
// Enable the OK button only when the textbox contains something.
|
||||
void OfflineLoginDialog::on_userTextBox_textEdited(const QString &newText)
|
||||
void OfflineLoginDialog::on_userTextBox_textEdited(const QString& newText)
|
||||
{
|
||||
ui->buttonBox->button(QDialogButtonBox::Ok)
|
||||
->setEnabled(!newText.isEmpty());
|
||||
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!newText.isEmpty());
|
||||
}
|
||||
|
||||
void OfflineLoginDialog::onTaskFailed(const QString &reason)
|
||||
void OfflineLoginDialog::onTaskFailed(const QString& reason)
|
||||
{
|
||||
// Set message
|
||||
auto lines = reason.split('\n');
|
||||
QString processed;
|
||||
for(auto line: lines) {
|
||||
if(line.size()) {
|
||||
for (auto line : lines) {
|
||||
if (line.size()) {
|
||||
processed += "<font color='red'>" + line + "</font><br />";
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
processed += "<br />";
|
||||
}
|
||||
}
|
||||
@ -83,7 +81,7 @@ void OfflineLoginDialog::onTaskSucceeded()
|
||||
QDialog::accept();
|
||||
}
|
||||
|
||||
void OfflineLoginDialog::onTaskStatus(const QString &status)
|
||||
void OfflineLoginDialog::onTaskStatus(const QString& status)
|
||||
{
|
||||
ui->label->setText(status);
|
||||
}
|
||||
@ -95,12 +93,11 @@ void OfflineLoginDialog::onTaskProgress(qint64 current, qint64 total)
|
||||
}
|
||||
|
||||
// Public interface
|
||||
MinecraftAccountPtr OfflineLoginDialog::newAccount(QWidget *parent, QString msg)
|
||||
MinecraftAccountPtr OfflineLoginDialog::newAccount(QWidget* parent, QString msg)
|
||||
{
|
||||
OfflineLoginDialog dlg(parent);
|
||||
dlg.ui->label->setText(msg);
|
||||
if (dlg.exec() == QDialog::Accepted)
|
||||
{
|
||||
if (dlg.exec() == QDialog::Accepted) {
|
||||
return dlg.m_account;
|
||||
}
|
||||
return nullptr;
|
||||
|
@ -1,44 +1,41 @@
|
||||
#pragma once
|
||||
|
||||
#include <QtWidgets/QDialog>
|
||||
#include <QtCore/QEventLoop>
|
||||
#include <QtWidgets/QDialog>
|
||||
|
||||
#include "minecraft/auth/MinecraftAccount.h"
|
||||
#include "tasks/Task.h"
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
namespace Ui {
|
||||
class OfflineLoginDialog;
|
||||
}
|
||||
|
||||
class OfflineLoginDialog : public QDialog
|
||||
{
|
||||
class OfflineLoginDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
public:
|
||||
~OfflineLoginDialog();
|
||||
|
||||
static MinecraftAccountPtr newAccount(QWidget *parent, QString message);
|
||||
static MinecraftAccountPtr newAccount(QWidget* parent, QString message);
|
||||
|
||||
private:
|
||||
explicit OfflineLoginDialog(QWidget *parent = 0);
|
||||
private:
|
||||
explicit OfflineLoginDialog(QWidget* parent = 0);
|
||||
|
||||
void setUserInputsEnabled(bool enable);
|
||||
|
||||
protected
|
||||
slots:
|
||||
protected slots:
|
||||
void accept();
|
||||
|
||||
void onTaskFailed(const QString &reason);
|
||||
void onTaskFailed(const QString& reason);
|
||||
void onTaskSucceeded();
|
||||
void onTaskStatus(const QString &status);
|
||||
void onTaskStatus(const QString& status);
|
||||
void onTaskProgress(qint64 current, qint64 total);
|
||||
|
||||
void on_userTextBox_textEdited(const QString &newText);
|
||||
void on_userTextBox_textEdited(const QString& newText);
|
||||
void on_allowLongUsernames_stateChanged(int value);
|
||||
|
||||
private:
|
||||
Ui::OfflineLoginDialog *ui;
|
||||
private:
|
||||
Ui::OfflineLoginDialog* ui;
|
||||
MinecraftAccountPtr m_account;
|
||||
Task::Ptr m_loginTask;
|
||||
};
|
||||
|
@ -16,43 +16,38 @@
|
||||
#include "ProfileSelectDialog.h"
|
||||
#include "ui_ProfileSelectDialog.h"
|
||||
|
||||
#include <QItemSelectionModel>
|
||||
#include <QDebug>
|
||||
#include <QItemSelectionModel>
|
||||
|
||||
#include "SkinUtils.h"
|
||||
#include "Application.h"
|
||||
#include "SkinUtils.h"
|
||||
|
||||
#include "ui/dialogs/ProgressDialog.h"
|
||||
|
||||
ProfileSelectDialog::ProfileSelectDialog(const QString &message, int flags, QWidget *parent)
|
||||
ProfileSelectDialog::ProfileSelectDialog(const QString& message, int flags, QWidget* parent)
|
||||
: QDialog(parent), ui(new Ui::ProfileSelectDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
m_accounts = APPLICATION->accounts();
|
||||
auto view = ui->listView;
|
||||
//view->setModel(m_accounts.get());
|
||||
//view->hideColumn(AccountList::ActiveColumn);
|
||||
// view->setModel(m_accounts.get());
|
||||
// view->hideColumn(AccountList::ActiveColumn);
|
||||
view->setColumnCount(1);
|
||||
view->setRootIsDecorated(false);
|
||||
// FIXME: use a real model, not this
|
||||
if(QTreeWidgetItem* header = view->headerItem())
|
||||
{
|
||||
if (QTreeWidgetItem* header = view->headerItem()) {
|
||||
header->setText(0, tr("Name"));
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
view->setHeaderLabel(tr("Name"));
|
||||
}
|
||||
QList <QTreeWidgetItem *> items;
|
||||
for (int i = 0; i < m_accounts->count(); i++)
|
||||
{
|
||||
QList<QTreeWidgetItem*> items;
|
||||
for (int i = 0; i < m_accounts->count(); i++) {
|
||||
MinecraftAccountPtr account = m_accounts->at(i);
|
||||
QString profileLabel;
|
||||
if(account->isInUse()) {
|
||||
if (account->isInUse()) {
|
||||
profileLabel = tr("%1 (in use)").arg(account->profileName());
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
profileLabel = account->profileName();
|
||||
}
|
||||
auto item = new QTreeWidgetItem(view);
|
||||
@ -101,8 +96,7 @@ bool ProfileSelectDialog::useAsInstDefaullt() const
|
||||
void ProfileSelectDialog::on_buttonBox_accepted()
|
||||
{
|
||||
QModelIndexList selection = ui->listView->selectionModel()->selectedIndexes();
|
||||
if (selection.size() > 0)
|
||||
{
|
||||
if (selection.size() > 0) {
|
||||
QModelIndex selected = selection.first();
|
||||
m_selected = selected.data(AccountList::PointerRole).value<MinecraftAccountPtr>();
|
||||
}
|
||||
|
@ -21,17 +21,14 @@
|
||||
|
||||
#include "minecraft/auth/AccountList.h"
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
namespace Ui {
|
||||
class ProfileSelectDialog;
|
||||
}
|
||||
|
||||
class ProfileSelectDialog : public QDialog
|
||||
{
|
||||
class ProfileSelectDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum Flags
|
||||
{
|
||||
public:
|
||||
enum Flags {
|
||||
NoFlags = 0,
|
||||
|
||||
/*!
|
||||
@ -52,7 +49,7 @@ public:
|
||||
* Constructs a new account select dialog with the given parent and message.
|
||||
* The message will be shown at the top of the dialog. It is an empty string by default.
|
||||
*/
|
||||
explicit ProfileSelectDialog(const QString& message="", int flags=0, QWidget *parent = 0);
|
||||
explicit ProfileSelectDialog(const QString& message = "", int flags = 0, QWidget* parent = 0);
|
||||
~ProfileSelectDialog();
|
||||
|
||||
/*!
|
||||
@ -73,18 +70,17 @@ public:
|
||||
*/
|
||||
bool useAsInstDefaullt() const;
|
||||
|
||||
public
|
||||
slots:
|
||||
public slots:
|
||||
void on_buttonBox_accepted();
|
||||
|
||||
void on_buttonBox_rejected();
|
||||
|
||||
protected:
|
||||
protected:
|
||||
shared_qobject_ptr<AccountList> m_accounts;
|
||||
|
||||
//! The account that was selected when the user clicked OK.
|
||||
MinecraftAccountPtr m_selected;
|
||||
|
||||
private:
|
||||
Ui::ProfileSelectDialog *ui;
|
||||
private:
|
||||
Ui::ProfileSelectDialog* ui;
|
||||
};
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
/*
|
||||
* PolyMC - Minecraft Launcher
|
||||
* Prism Launcher - Minecraft Launcher
|
||||
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
@ -36,11 +36,11 @@
|
||||
#include "ProfileSetupDialog.h"
|
||||
#include "ui_ProfileSetupDialog.h"
|
||||
|
||||
#include <QPushButton>
|
||||
#include <QAction>
|
||||
#include <QRegularExpressionValidator>
|
||||
#include <QJsonDocument>
|
||||
#include <QDebug>
|
||||
#include <QJsonDocument>
|
||||
#include <QPushButton>
|
||||
#include <QRegularExpressionValidator>
|
||||
|
||||
#include "ui/dialogs/ProgressDialog.h"
|
||||
|
||||
@ -48,8 +48,7 @@
|
||||
#include "minecraft/auth/AuthRequest.h"
|
||||
#include "minecraft/auth/Parsers.h"
|
||||
|
||||
|
||||
ProfileSetupDialog::ProfileSetupDialog(MinecraftAccountPtr accountToSetup, QWidget *parent)
|
||||
ProfileSetupDialog::ProfileSetupDialog(MinecraftAccountPtr accountToSetup, QWidget* parent)
|
||||
: QDialog(parent), m_accountToSetup(accountToSetup), ui(new Ui::ProfileSetupDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
@ -91,13 +90,11 @@ void ProfileSetupDialog::setNameStatus(ProfileSetupDialog::NameStatus status, QS
|
||||
{
|
||||
nameStatus = status;
|
||||
auto okButton = ui->buttonBox->button(QDialogButtonBox::Ok);
|
||||
switch(nameStatus)
|
||||
{
|
||||
switch (nameStatus) {
|
||||
case NameStatus::Available: {
|
||||
validityAction->setIcon(goodIcon);
|
||||
okButton->setEnabled(true);
|
||||
}
|
||||
break;
|
||||
} break;
|
||||
case NameStatus::NotSet:
|
||||
case NameStatus::Pending:
|
||||
validityAction->setIcon(yellowIcon);
|
||||
@ -109,43 +106,44 @@ void ProfileSetupDialog::setNameStatus(ProfileSetupDialog::NameStatus status, QS
|
||||
okButton->setEnabled(false);
|
||||
break;
|
||||
}
|
||||
if(!errorString.isEmpty()) {
|
||||
if (!errorString.isEmpty()) {
|
||||
ui->errorLabel->setText(errorString);
|
||||
ui->errorLabel->setVisible(true);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
ui->errorLabel->setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
void ProfileSetupDialog::nameEdited(const QString& name)
|
||||
{
|
||||
if(!ui->nameEdit->hasAcceptableInput()) {
|
||||
if (!ui->nameEdit->hasAcceptableInput()) {
|
||||
setNameStatus(NameStatus::NotSet, tr("Name is too short - must be between 3 and 16 characters long."));
|
||||
return;
|
||||
}
|
||||
scheduleCheck(name);
|
||||
}
|
||||
|
||||
void ProfileSetupDialog::scheduleCheck(const QString& name) {
|
||||
void ProfileSetupDialog::scheduleCheck(const QString& name)
|
||||
{
|
||||
queuedCheck = name;
|
||||
setNameStatus(NameStatus::Pending);
|
||||
checkStartTimer.start(1000);
|
||||
}
|
||||
|
||||
void ProfileSetupDialog::startCheck() {
|
||||
if(isChecking) {
|
||||
void ProfileSetupDialog::startCheck()
|
||||
{
|
||||
if (isChecking) {
|
||||
return;
|
||||
}
|
||||
if(queuedCheck.isNull()) {
|
||||
if (queuedCheck.isNull()) {
|
||||
return;
|
||||
}
|
||||
checkName(queuedCheck);
|
||||
}
|
||||
|
||||
|
||||
void ProfileSetupDialog::checkName(const QString &name) {
|
||||
if(isChecking) {
|
||||
void ProfileSetupDialog::checkName(const QString& name)
|
||||
{
|
||||
if (isChecking) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -160,44 +158,38 @@ void ProfileSetupDialog::checkName(const QString &name) {
|
||||
request.setRawHeader("Accept", "application/json");
|
||||
request.setRawHeader("Authorization", QString("Bearer %1").arg(token).toUtf8());
|
||||
|
||||
AuthRequest *requestor = new AuthRequest(this);
|
||||
AuthRequest* requestor = new AuthRequest(this);
|
||||
connect(requestor, &AuthRequest::finished, this, &ProfileSetupDialog::checkFinished);
|
||||
requestor->get(request);
|
||||
}
|
||||
|
||||
void ProfileSetupDialog::checkFinished(
|
||||
QNetworkReply::NetworkError error,
|
||||
QByteArray data,
|
||||
QList<QNetworkReply::RawHeaderPair> headers
|
||||
) {
|
||||
auto requestor = qobject_cast<AuthRequest *>(QObject::sender());
|
||||
void ProfileSetupDialog::checkFinished(QNetworkReply::NetworkError error, QByteArray data, QList<QNetworkReply::RawHeaderPair> headers)
|
||||
{
|
||||
auto requestor = qobject_cast<AuthRequest*>(QObject::sender());
|
||||
requestor->deleteLater();
|
||||
|
||||
if(error == QNetworkReply::NoError) {
|
||||
if (error == QNetworkReply::NoError) {
|
||||
auto doc = QJsonDocument::fromJson(data);
|
||||
auto root = doc.object();
|
||||
auto statusValue = root.value("status").toString("INVALID");
|
||||
if(statusValue == "AVAILABLE") {
|
||||
if (statusValue == "AVAILABLE") {
|
||||
setNameStatus(NameStatus::Available);
|
||||
}
|
||||
else if (statusValue == "DUPLICATE") {
|
||||
} else if (statusValue == "DUPLICATE") {
|
||||
setNameStatus(NameStatus::Exists, tr("Minecraft profile with name %1 already exists.").arg(currentCheck));
|
||||
}
|
||||
else if (statusValue == "NOT_ALLOWED") {
|
||||
} else if (statusValue == "NOT_ALLOWED") {
|
||||
setNameStatus(NameStatus::Exists, tr("The name %1 is not allowed.").arg(currentCheck));
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
setNameStatus(NameStatus::Error, tr("Unhandled profile name status: %1").arg(statusValue));
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
setNameStatus(NameStatus::Error, tr("Failed to check name availability."));
|
||||
}
|
||||
isChecking = false;
|
||||
}
|
||||
|
||||
void ProfileSetupDialog::setupProfile(const QString &profileName) {
|
||||
if(isWorking) {
|
||||
void ProfileSetupDialog::setupProfile(const QString& profileName)
|
||||
{
|
||||
if (isWorking) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -212,7 +204,7 @@ void ProfileSetupDialog::setupProfile(const QString &profileName) {
|
||||
QString payloadTemplate("{\"profileName\":\"%1\"}");
|
||||
auto data = payloadTemplate.arg(profileName).toUtf8();
|
||||
|
||||
AuthRequest *requestor = new AuthRequest(this);
|
||||
AuthRequest* requestor = new AuthRequest(this);
|
||||
connect(requestor, &AuthRequest::finished, this, &ProfileSetupDialog::setupProfileFinished);
|
||||
requestor->post(request, data);
|
||||
isWorking = true;
|
||||
@ -223,8 +215,9 @@ void ProfileSetupDialog::setupProfile(const QString &profileName) {
|
||||
|
||||
namespace {
|
||||
|
||||
struct MojangError{
|
||||
static MojangError fromJSON(QByteArray data) {
|
||||
struct MojangError {
|
||||
static MojangError fromJSON(QByteArray data)
|
||||
{
|
||||
MojangError out;
|
||||
out.error = QString::fromUtf8(data);
|
||||
auto doc = QJsonDocument::fromJson(data, &out.parseError);
|
||||
@ -247,25 +240,23 @@ struct MojangError{
|
||||
QString errorMessage;
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void ProfileSetupDialog::setupProfileFinished(
|
||||
QNetworkReply::NetworkError error,
|
||||
QByteArray data,
|
||||
QList<QNetworkReply::RawHeaderPair> headers
|
||||
) {
|
||||
auto requestor = qobject_cast<AuthRequest *>(QObject::sender());
|
||||
void ProfileSetupDialog::setupProfileFinished(QNetworkReply::NetworkError error,
|
||||
QByteArray data,
|
||||
QList<QNetworkReply::RawHeaderPair> headers)
|
||||
{
|
||||
auto requestor = qobject_cast<AuthRequest*>(QObject::sender());
|
||||
requestor->deleteLater();
|
||||
|
||||
isWorking = false;
|
||||
if(error == QNetworkReply::NoError) {
|
||||
if (error == QNetworkReply::NoError) {
|
||||
/*
|
||||
* data contains the profile in the response
|
||||
* ... we could parse it and update the account, but let's just return back to the normal login flow instead...
|
||||
*/
|
||||
accept();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
auto parsedError = MojangError::fromJSON(data);
|
||||
ui->errorLabel->setVisible(true);
|
||||
ui->errorLabel->setText(tr("The server returned the following error:") + "\n\n" + parsedError.errorMessage);
|
||||
|
@ -17,65 +17,48 @@
|
||||
|
||||
#include <QDialog>
|
||||
#include <QIcon>
|
||||
#include <QTimer>
|
||||
#include <QNetworkReply>
|
||||
#include <QTimer>
|
||||
|
||||
#include <memory>
|
||||
#include <minecraft/auth/MinecraftAccount.h>
|
||||
#include <memory>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
namespace Ui {
|
||||
class ProfileSetupDialog;
|
||||
}
|
||||
|
||||
class ProfileSetupDialog : public QDialog
|
||||
{
|
||||
class ProfileSetupDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
explicit ProfileSetupDialog(MinecraftAccountPtr accountToSetup, QWidget *parent = 0);
|
||||
public:
|
||||
explicit ProfileSetupDialog(MinecraftAccountPtr accountToSetup, QWidget* parent = 0);
|
||||
~ProfileSetupDialog();
|
||||
|
||||
enum class NameStatus
|
||||
{
|
||||
NotSet,
|
||||
Pending,
|
||||
Available,
|
||||
Exists,
|
||||
Error
|
||||
} nameStatus = NameStatus::NotSet;
|
||||
enum class NameStatus { NotSet, Pending, Available, Exists, Error } nameStatus = NameStatus::NotSet;
|
||||
|
||||
private slots:
|
||||
private slots:
|
||||
void on_buttonBox_accepted();
|
||||
void on_buttonBox_rejected();
|
||||
|
||||
void nameEdited(const QString &name);
|
||||
void checkFinished(
|
||||
QNetworkReply::NetworkError error,
|
||||
QByteArray data,
|
||||
QList<QNetworkReply::RawHeaderPair> headers
|
||||
);
|
||||
void nameEdited(const QString& name);
|
||||
void checkFinished(QNetworkReply::NetworkError error, QByteArray data, QList<QNetworkReply::RawHeaderPair> headers);
|
||||
void startCheck();
|
||||
|
||||
void setupProfileFinished(
|
||||
QNetworkReply::NetworkError error,
|
||||
QByteArray data,
|
||||
QList<QNetworkReply::RawHeaderPair> headers
|
||||
);
|
||||
protected:
|
||||
void scheduleCheck(const QString &name);
|
||||
void checkName(const QString &name);
|
||||
void setupProfileFinished(QNetworkReply::NetworkError error, QByteArray data, QList<QNetworkReply::RawHeaderPair> headers);
|
||||
|
||||
protected:
|
||||
void scheduleCheck(const QString& name);
|
||||
void checkName(const QString& name);
|
||||
void setNameStatus(NameStatus status, QString errorString);
|
||||
|
||||
void setupProfile(const QString & profileName);
|
||||
void setupProfile(const QString& profileName);
|
||||
|
||||
private:
|
||||
private:
|
||||
MinecraftAccountPtr m_accountToSetup;
|
||||
Ui::ProfileSetupDialog *ui;
|
||||
Ui::ProfileSetupDialog* ui;
|
||||
QIcon goodIcon;
|
||||
QIcon yellowIcon;
|
||||
QIcon badIcon;
|
||||
QAction * validityAction = nullptr;
|
||||
QAction* validityAction = nullptr;
|
||||
|
||||
QString queuedCheck;
|
||||
|
||||
@ -85,4 +68,3 @@ private:
|
||||
|
||||
QTimer checkStartTimer;
|
||||
};
|
||||
|
||||
|
@ -37,18 +37,17 @@
|
||||
#include <QPoint>
|
||||
#include "ui_ProgressDialog.h"
|
||||
|
||||
#include <limits>
|
||||
#include <QDebug>
|
||||
#include <QKeyEvent>
|
||||
#include <limits>
|
||||
|
||||
#include "tasks/Task.h"
|
||||
|
||||
#include "ui/widgets/SubTaskProgressBar.h"
|
||||
|
||||
|
||||
// map a value in a numeric range of an arbitrary type to between 0 and INT_MAX
|
||||
// for getting the best precision out of the qt progress bar
|
||||
template<typename T, std::enable_if_t<std::is_arithmetic_v<T>, bool> = true>
|
||||
template <typename T, std::enable_if_t<std::is_arithmetic_v<T>, bool> = true>
|
||||
std::tuple<int, int> map_int_zero_max(T current, T range_max, T range_min)
|
||||
{
|
||||
int int_max = std::numeric_limits<int>::max();
|
||||
@ -57,10 +56,9 @@ std::tuple<int, int> map_int_zero_max(T current, T range_max, T range_min)
|
||||
double percentage = static_cast<double>(current - range_min) / static_cast<double>(type_range);
|
||||
int mapped_current = percentage * int_max;
|
||||
|
||||
return {mapped_current, int_max};
|
||||
return { mapped_current, int_max };
|
||||
}
|
||||
|
||||
|
||||
ProgressDialog::ProgressDialog(QWidget* parent) : QDialog(parent), ui(new Ui::ProgressDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
@ -96,7 +94,7 @@ ProgressDialog::~ProgressDialog()
|
||||
}
|
||||
|
||||
void ProgressDialog::updateSize(bool recenterParent)
|
||||
{
|
||||
{
|
||||
QSize lastSize = this->size();
|
||||
QPoint lastPos = this->pos();
|
||||
int minHeight = ui->globalStatusDetailsLabel->minimumSize().height() + (ui->verticalLayout->spacing() * 2);
|
||||
@ -118,16 +116,13 @@ void ProgressDialog::updateSize(bool recenterParent)
|
||||
auto newX = std::max(0, parent->x() + ((parent->width() - newSize.width()) / 2));
|
||||
auto newY = std::max(0, parent->y() + ((parent->height() - newSize.height()) / 2));
|
||||
this->move(newX, newY);
|
||||
}
|
||||
else if (lastSize != newSize)
|
||||
{
|
||||
} else if (lastSize != newSize) {
|
||||
// center on old position after resize
|
||||
QSize sizeDiff = lastSize - newSize; // last size was smaller, the results should be negative
|
||||
QSize sizeDiff = lastSize - newSize; // last size was smaller, the results should be negative
|
||||
auto newX = std::max(0, lastPos.x() + (sizeDiff.width() / 2));
|
||||
auto newY = std::max(0, lastPos.y() + (sizeDiff.height() / 2));
|
||||
this->move(newX, newY);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int ProgressDialog::execWithTask(Task* task)
|
||||
@ -139,7 +134,7 @@ int ProgressDialog::execWithTask(Task* task)
|
||||
return QDialog::DialogCode::Accepted;
|
||||
}
|
||||
|
||||
QDialog::DialogCode result {};
|
||||
QDialog::DialogCode result{};
|
||||
if (handleImmediateResult(result)) {
|
||||
return result;
|
||||
}
|
||||
@ -234,16 +229,15 @@ void ProgressDialog::addTaskProgress(TaskStepProgress const& progress)
|
||||
void ProgressDialog::changeStepProgress(TaskStepProgress const& task_progress)
|
||||
{
|
||||
m_is_multi_step = true;
|
||||
if(ui->taskProgressScrollArea->isHidden()) {
|
||||
if (ui->taskProgressScrollArea->isHidden()) {
|
||||
ui->taskProgressScrollArea->setHidden(false);
|
||||
updateSize();
|
||||
}
|
||||
|
||||
|
||||
if (!taskProgress.contains(task_progress.uid))
|
||||
addTaskProgress(task_progress);
|
||||
auto task_bar = taskProgress.value(task_progress.uid);
|
||||
|
||||
|
||||
auto const [mapped_current, mapped_total] = map_int_zero_max<qint64>(task_progress.current, task_progress.total, 0);
|
||||
if (task_progress.total <= 0) {
|
||||
task_bar->setRange(0, 0);
|
||||
@ -258,14 +252,12 @@ void ProgressDialog::changeStepProgress(TaskStepProgress const& task_progress)
|
||||
if (task_progress.isDone()) {
|
||||
task_bar->setVisible(false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ProgressDialog::changeProgress(qint64 current, qint64 total)
|
||||
{
|
||||
ui->globalProgressBar->setMaximum(total);
|
||||
ui->globalProgressBar->setValue(current);
|
||||
|
||||
}
|
||||
|
||||
void ProgressDialog::keyPressEvent(QKeyEvent* e)
|
||||
|
@ -33,13 +33,12 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QDialog>
|
||||
#include <memory>
|
||||
#include <QHash>
|
||||
#include <QUuid>
|
||||
#include <memory>
|
||||
|
||||
#include "QObjectPtr.h"
|
||||
#include "tasks/Task.h"
|
||||
@ -49,60 +48,52 @@
|
||||
class Task;
|
||||
class SequentialTask;
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
namespace Ui {
|
||||
class ProgressDialog;
|
||||
}
|
||||
|
||||
class ProgressDialog : public QDialog
|
||||
{
|
||||
class ProgressDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ProgressDialog(QWidget *parent = 0);
|
||||
public:
|
||||
explicit ProgressDialog(QWidget* parent = 0);
|
||||
~ProgressDialog();
|
||||
|
||||
void updateSize(bool recenterParent = false);
|
||||
|
||||
int execWithTask(Task* task);
|
||||
int execWithTask(std::unique_ptr<Task> &&task);
|
||||
int execWithTask(std::unique_ptr<Task> &task);
|
||||
int execWithTask(std::unique_ptr<Task>&& task);
|
||||
int execWithTask(std::unique_ptr<Task>& task);
|
||||
|
||||
void setSkipButton(bool present, QString label = QString());
|
||||
|
||||
Task *getTask();
|
||||
Task* getTask();
|
||||
|
||||
public
|
||||
slots:
|
||||
public slots:
|
||||
void onTaskStarted();
|
||||
void onTaskFailed(QString failure);
|
||||
void onTaskSucceeded();
|
||||
|
||||
void changeStatus(const QString &status);
|
||||
void changeStatus(const QString& status);
|
||||
void changeProgress(qint64 current, qint64 total);
|
||||
void changeStepProgress(TaskStepProgress const& task_progress);
|
||||
|
||||
|
||||
private
|
||||
slots:
|
||||
private slots:
|
||||
void on_skipButton_clicked(bool checked);
|
||||
|
||||
protected:
|
||||
virtual void keyPressEvent(QKeyEvent *e);
|
||||
virtual void closeEvent(QCloseEvent *e);
|
||||
protected:
|
||||
virtual void keyPressEvent(QKeyEvent* e);
|
||||
virtual void closeEvent(QCloseEvent* e);
|
||||
|
||||
private:
|
||||
bool handleImmediateResult(QDialog::DialogCode &result);
|
||||
private:
|
||||
bool handleImmediateResult(QDialog::DialogCode& result);
|
||||
void addTaskProgress(TaskStepProgress const& progress);
|
||||
|
||||
private:
|
||||
Ui::ProgressDialog *ui;
|
||||
private:
|
||||
Ui::ProgressDialog* ui;
|
||||
|
||||
Task *task;
|
||||
Task* task;
|
||||
|
||||
bool m_is_multi_step = false;
|
||||
QHash<QUuid, SubTaskProgressBar*> taskProgress;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
@ -1,15 +1,16 @@
|
||||
#include "ScrollMessageBox.h"
|
||||
#include "ui_ScrollMessageBox.h"
|
||||
|
||||
|
||||
ScrollMessageBox::ScrollMessageBox(QWidget *parent, const QString &title, const QString &text, const QString &body) :
|
||||
QDialog(parent), ui(new Ui::ScrollMessageBox) {
|
||||
ScrollMessageBox::ScrollMessageBox(QWidget* parent, const QString& title, const QString& text, const QString& body)
|
||||
: QDialog(parent), ui(new Ui::ScrollMessageBox)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
this->setWindowTitle(title);
|
||||
ui->label->setText(text);
|
||||
ui->textBrowser->setText(body);
|
||||
}
|
||||
|
||||
ScrollMessageBox::~ScrollMessageBox() {
|
||||
ScrollMessageBox::~ScrollMessageBox()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
@ -2,19 +2,20 @@
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
namespace Ui { class ScrollMessageBox; }
|
||||
namespace Ui {
|
||||
class ScrollMessageBox;
|
||||
}
|
||||
QT_END_NAMESPACE
|
||||
|
||||
class ScrollMessageBox : public QDialog {
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ScrollMessageBox(QWidget *parent, const QString &title, const QString &text, const QString &body);
|
||||
public:
|
||||
ScrollMessageBox(QWidget* parent, const QString& title, const QString& text, const QString& body);
|
||||
|
||||
~ScrollMessageBox() override;
|
||||
|
||||
private:
|
||||
Ui::ScrollMessageBox *ui;
|
||||
private:
|
||||
Ui::ScrollMessageBox* ui;
|
||||
};
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
/*
|
||||
* PolyMC - Minecraft Launcher
|
||||
* Prism Launcher - Minecraft Launcher
|
||||
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
@ -33,20 +33,20 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <QFileInfo>
|
||||
#include <QFileDialog>
|
||||
#include <QFileInfo>
|
||||
#include <QPainter>
|
||||
|
||||
#include <FileSystem.h>
|
||||
|
||||
#include <minecraft/services/SkinUpload.h>
|
||||
#include <minecraft/services/CapeChange.h>
|
||||
#include <minecraft/services/SkinUpload.h>
|
||||
#include <tasks/SequentialTask.h>
|
||||
|
||||
#include "CustomMessageBox.h"
|
||||
#include "ProgressDialog.h"
|
||||
#include "SkinUploadDialog.h"
|
||||
#include "ui_SkinUploadDialog.h"
|
||||
#include "ProgressDialog.h"
|
||||
#include "CustomMessageBox.h"
|
||||
|
||||
void SkinUploadDialog::on_buttonBox_rejected()
|
||||
{
|
||||
@ -64,71 +64,51 @@ void SkinUploadDialog::on_buttonBox_accepted()
|
||||
QRegularExpression urlPrefixMatcher(QRegularExpression::anchoredPattern("^([a-z]+)://.+$"));
|
||||
bool isLocalFile = false;
|
||||
// it has an URL prefix -> it is an URL
|
||||
if(urlPrefixMatcher.match(input).hasMatch())
|
||||
{
|
||||
if (urlPrefixMatcher.match(input).hasMatch()) {
|
||||
QUrl fileURL = input;
|
||||
if(fileURL.isValid())
|
||||
{
|
||||
if (fileURL.isValid()) {
|
||||
// local?
|
||||
if(fileURL.isLocalFile())
|
||||
{
|
||||
if (fileURL.isLocalFile()) {
|
||||
isLocalFile = true;
|
||||
fileName = fileURL.toLocalFile();
|
||||
}
|
||||
else
|
||||
{
|
||||
CustomMessageBox::selectable(
|
||||
this,
|
||||
tr("Skin Upload"),
|
||||
tr("Using remote URLs for setting skins is not implemented yet."),
|
||||
QMessageBox::Warning
|
||||
)->exec();
|
||||
} else {
|
||||
CustomMessageBox::selectable(this, tr("Skin Upload"), tr("Using remote URLs for setting skins is not implemented yet."),
|
||||
QMessageBox::Warning)
|
||||
->exec();
|
||||
close();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CustomMessageBox::selectable(
|
||||
this,
|
||||
tr("Skin Upload"),
|
||||
tr("You cannot use an invalid URL for uploading skins."),
|
||||
QMessageBox::Warning
|
||||
)->exec();
|
||||
} else {
|
||||
CustomMessageBox::selectable(this, tr("Skin Upload"), tr("You cannot use an invalid URL for uploading skins."),
|
||||
QMessageBox::Warning)
|
||||
->exec();
|
||||
close();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// just assume it's a path then
|
||||
isLocalFile = true;
|
||||
fileName = ui->skinPathTextBox->text();
|
||||
}
|
||||
if (isLocalFile && !QFile::exists(fileName))
|
||||
{
|
||||
if (isLocalFile && !QFile::exists(fileName)) {
|
||||
CustomMessageBox::selectable(this, tr("Skin Upload"), tr("Skin file does not exist!"), QMessageBox::Warning)->exec();
|
||||
close();
|
||||
return;
|
||||
}
|
||||
SkinUpload::Model model = SkinUpload::STEVE;
|
||||
if (ui->steveBtn->isChecked())
|
||||
{
|
||||
if (ui->steveBtn->isChecked()) {
|
||||
model = SkinUpload::STEVE;
|
||||
}
|
||||
else if (ui->alexBtn->isChecked())
|
||||
{
|
||||
} else if (ui->alexBtn->isChecked()) {
|
||||
model = SkinUpload::ALEX;
|
||||
}
|
||||
skinUpload.addTask(shared_qobject_ptr<SkinUpload>(new SkinUpload(this, m_acct->accessToken(), FS::read(fileName), model)));
|
||||
}
|
||||
|
||||
auto selectedCape = ui->capeCombo->currentData().toString();
|
||||
if(selectedCape != m_acct->accountData()->minecraftProfile.currentCape) {
|
||||
if (selectedCape != m_acct->accountData()->minecraftProfile.currentCape) {
|
||||
skinUpload.addTask(shared_qobject_ptr<CapeChange>(new CapeChange(this, m_acct->accessToken(), selectedCape)));
|
||||
}
|
||||
if (prog.execWithTask(&skinUpload) != QDialog::Accepted)
|
||||
{
|
||||
if (prog.execWithTask(&skinUpload) != QDialog::Accepted) {
|
||||
CustomMessageBox::selectable(this, tr("Skin Upload"), tr("Failed to upload skin!"), QMessageBox::Warning)->exec();
|
||||
close();
|
||||
return;
|
||||
@ -141,45 +121,43 @@ void SkinUploadDialog::on_skinBrowseBtn_clicked()
|
||||
{
|
||||
auto filter = QMimeDatabase().mimeTypeForName("image/png").filterString();
|
||||
QString raw_path = QFileDialog::getOpenFileName(this, tr("Select Skin Texture"), QString(), filter);
|
||||
if (raw_path.isEmpty() || !QFileInfo::exists(raw_path))
|
||||
{
|
||||
if (raw_path.isEmpty() || !QFileInfo::exists(raw_path)) {
|
||||
return;
|
||||
}
|
||||
QString cooked_path = FS::NormalizePath(raw_path);
|
||||
ui->skinPathTextBox->setText(cooked_path);
|
||||
}
|
||||
|
||||
SkinUploadDialog::SkinUploadDialog(MinecraftAccountPtr acct, QWidget *parent)
|
||||
:QDialog(parent), m_acct(acct), ui(new Ui::SkinUploadDialog)
|
||||
SkinUploadDialog::SkinUploadDialog(MinecraftAccountPtr acct, QWidget* parent) : QDialog(parent), m_acct(acct), ui(new Ui::SkinUploadDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
// FIXME: add a model for this, download/refresh the capes on demand
|
||||
auto &data = *acct->accountData();
|
||||
auto& data = *acct->accountData();
|
||||
int index = 0;
|
||||
ui->capeCombo->addItem(tr("No Cape"), QVariant());
|
||||
auto currentCape = data.minecraftProfile.currentCape;
|
||||
if(currentCape.isEmpty()) {
|
||||
if (currentCape.isEmpty()) {
|
||||
ui->capeCombo->setCurrentIndex(index);
|
||||
}
|
||||
|
||||
for(auto & cape: data.minecraftProfile.capes) {
|
||||
for (auto& cape : data.minecraftProfile.capes) {
|
||||
index++;
|
||||
if(cape.data.size()) {
|
||||
if (cape.data.size()) {
|
||||
QPixmap capeImage;
|
||||
if(capeImage.loadFromData(cape.data, "PNG")) {
|
||||
if (capeImage.loadFromData(cape.data, "PNG")) {
|
||||
QPixmap preview = QPixmap(10, 16);
|
||||
QPainter painter(&preview);
|
||||
painter.drawPixmap(0, 0, capeImage.copy(1, 1, 10, 16));
|
||||
ui->capeCombo->addItem(capeImage, cape.alias, cape.id);
|
||||
if(currentCape == cape.id) {
|
||||
if (currentCape == cape.id) {
|
||||
ui->capeCombo->setCurrentIndex(index);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
ui->capeCombo->addItem(cape.alias, cape.id);
|
||||
if(currentCape == cape.id) {
|
||||
if (currentCape == cape.id) {
|
||||
ui->capeCombo->setCurrentIndex(index);
|
||||
}
|
||||
}
|
||||
|
@ -1,29 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
#include <QDialog>
|
||||
#include <minecraft/auth/MinecraftAccount.h>
|
||||
#include <QDialog>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class SkinUploadDialog;
|
||||
namespace Ui {
|
||||
class SkinUploadDialog;
|
||||
}
|
||||
|
||||
class SkinUploadDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit SkinUploadDialog(MinecraftAccountPtr acct, QWidget *parent = 0);
|
||||
virtual ~SkinUploadDialog() {};
|
||||
public:
|
||||
explicit SkinUploadDialog(MinecraftAccountPtr acct, QWidget* parent = 0);
|
||||
virtual ~SkinUploadDialog(){};
|
||||
|
||||
public slots:
|
||||
public slots:
|
||||
void on_buttonBox_accepted();
|
||||
|
||||
void on_buttonBox_rejected();
|
||||
|
||||
void on_skinBrowseBtn_clicked();
|
||||
|
||||
protected:
|
||||
protected:
|
||||
MinecraftAccountPtr m_acct;
|
||||
|
||||
private:
|
||||
Ui::SkinUploadDialog *ui;
|
||||
private:
|
||||
Ui::SkinUploadDialog* ui;
|
||||
};
|
||||
|
@ -35,20 +35,19 @@
|
||||
|
||||
#include "VersionSelectDialog.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QtWidgets/QButtonGroup>
|
||||
#include <QtWidgets/QDialogButtonBox>
|
||||
#include <QtWidgets/QHBoxLayout>
|
||||
#include <QtWidgets/QPushButton>
|
||||
#include <QtWidgets/QVBoxLayout>
|
||||
#include <QDebug>
|
||||
|
||||
#include "ui/widgets/VersionSelectWidget.h"
|
||||
|
||||
#include "BaseVersion.h"
|
||||
#include "BaseVersionList.h"
|
||||
|
||||
VersionSelectDialog::VersionSelectDialog(BaseVersionList *vlist, QString title, QWidget *parent, bool cancelable)
|
||||
: QDialog(parent)
|
||||
VersionSelectDialog::VersionSelectDialog(BaseVersionList* vlist, QString title, QWidget* parent, bool cancelable) : QDialog(parent)
|
||||
{
|
||||
setObjectName(QStringLiteral("VersionSelectDialog"));
|
||||
resize(400, 347);
|
||||
@ -68,7 +67,7 @@ VersionSelectDialog::VersionSelectDialog(BaseVersionList *vlist, QString title,
|
||||
m_buttonBox = new QDialogButtonBox(this);
|
||||
m_buttonBox->setObjectName(QStringLiteral("buttonBox"));
|
||||
m_buttonBox->setOrientation(Qt::Horizontal);
|
||||
m_buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok);
|
||||
m_buttonBox->setStandardButtons(QDialogButtonBox::Cancel | QDialogButtonBox::Ok);
|
||||
m_horizontalLayout->addWidget(m_buttonBox);
|
||||
|
||||
m_verticalLayout->addLayout(m_horizontalLayout);
|
||||
@ -84,8 +83,7 @@ VersionSelectDialog::VersionSelectDialog(BaseVersionList *vlist, QString title,
|
||||
|
||||
m_vlist = vlist;
|
||||
|
||||
if (!cancelable)
|
||||
{
|
||||
if (!cancelable) {
|
||||
m_buttonBox->button(QDialogButtonBox::Cancel)->setEnabled(false);
|
||||
}
|
||||
}
|
||||
@ -123,8 +121,7 @@ int VersionSelectDialog::exec()
|
||||
{
|
||||
QDialog::open();
|
||||
m_versionWidget->initialize(m_vlist);
|
||||
if(resizeOnColumn != -1)
|
||||
{
|
||||
if (resizeOnColumn != -1) {
|
||||
m_versionWidget->setResizeOn(resizeOnColumn);
|
||||
}
|
||||
return QDialog::exec();
|
||||
|
@ -18,7 +18,6 @@
|
||||
#include <QDialog>
|
||||
#include <QSortFilterProxyModel>
|
||||
|
||||
|
||||
#include "BaseVersionList.h"
|
||||
|
||||
class QVBoxLayout;
|
||||
@ -27,52 +26,50 @@ class QDialogButtonBox;
|
||||
class VersionSelectWidget;
|
||||
class QPushButton;
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
namespace Ui {
|
||||
class VersionSelectDialog;
|
||||
}
|
||||
|
||||
class VersionProxyModel;
|
||||
|
||||
class VersionSelectDialog : public QDialog
|
||||
{
|
||||
class VersionSelectDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit VersionSelectDialog(BaseVersionList *vlist, QString title, QWidget *parent = 0, bool cancelable = true);
|
||||
virtual ~VersionSelectDialog() {};
|
||||
public:
|
||||
explicit VersionSelectDialog(BaseVersionList* vlist, QString title, QWidget* parent = 0, bool cancelable = true);
|
||||
virtual ~VersionSelectDialog(){};
|
||||
|
||||
int exec() override;
|
||||
|
||||
BaseVersion::Ptr selectedVersion() const;
|
||||
|
||||
void setCurrentVersion(const QString & version);
|
||||
void setCurrentVersion(const QString& version);
|
||||
void setFuzzyFilter(BaseVersionList::ModelRoles role, QString filter);
|
||||
void setExactFilter(BaseVersionList::ModelRoles role, QString filter);
|
||||
void setEmptyString(QString emptyString);
|
||||
void setEmptyErrorString(QString emptyErrorString);
|
||||
void setResizeOn(int column);
|
||||
|
||||
private slots:
|
||||
private slots:
|
||||
void on_refreshButton_clicked();
|
||||
|
||||
private:
|
||||
private:
|
||||
void retranslate();
|
||||
void selectRecommended();
|
||||
|
||||
private:
|
||||
private:
|
||||
QString m_currentVersion;
|
||||
VersionSelectWidget *m_versionWidget = nullptr;
|
||||
QVBoxLayout *m_verticalLayout = nullptr;
|
||||
QHBoxLayout *m_horizontalLayout = nullptr;
|
||||
QPushButton *m_refreshButton = nullptr;
|
||||
QDialogButtonBox *m_buttonBox = nullptr;
|
||||
VersionSelectWidget* m_versionWidget = nullptr;
|
||||
QVBoxLayout* m_verticalLayout = nullptr;
|
||||
QHBoxLayout* m_horizontalLayout = nullptr;
|
||||
QPushButton* m_refreshButton = nullptr;
|
||||
QDialogButtonBox* m_buttonBox = nullptr;
|
||||
|
||||
BaseVersionList *m_vlist = nullptr;
|
||||
BaseVersionList* m_vlist = nullptr;
|
||||
|
||||
VersionProxyModel *m_proxyModel = nullptr;
|
||||
VersionProxyModel* m_proxyModel = nullptr;
|
||||
|
||||
int resizeOnColumn = -1;
|
||||
|
||||
Task * loadTask = nullptr;
|
||||
Task* loadTask = nullptr;
|
||||
};
|
||||
|
@ -1,42 +1,40 @@
|
||||
#include "InstanceView.h"
|
||||
#include "AccessibleInstanceView.h"
|
||||
#include "AccessibleInstanceView_p.h"
|
||||
#include "InstanceView.h"
|
||||
|
||||
#include <qvariant.h>
|
||||
#include <qaccessible.h>
|
||||
#include <qheaderview.h>
|
||||
#include <qvariant.h>
|
||||
|
||||
#ifndef QT_NO_ACCESSIBILITY
|
||||
|
||||
QAccessibleInterface *groupViewAccessibleFactory(const QString &classname, QObject *object)
|
||||
QAccessibleInterface* groupViewAccessibleFactory(const QString& classname, QObject* object)
|
||||
{
|
||||
QAccessibleInterface *iface = 0;
|
||||
QAccessibleInterface* iface = 0;
|
||||
if (!object || !object->isWidgetType())
|
||||
return iface;
|
||||
|
||||
QWidget *widget = static_cast<QWidget*>(object);
|
||||
QWidget* widget = static_cast<QWidget*>(object);
|
||||
|
||||
if (classname == QLatin1String("InstanceView")) {
|
||||
iface = new AccessibleInstanceView((InstanceView *)widget);
|
||||
iface = new AccessibleInstanceView((InstanceView*)widget);
|
||||
}
|
||||
return iface;
|
||||
}
|
||||
|
||||
|
||||
QAbstractItemView *AccessibleInstanceView::view() const
|
||||
QAbstractItemView* AccessibleInstanceView::view() const
|
||||
{
|
||||
return qobject_cast<QAbstractItemView*>(object());
|
||||
}
|
||||
|
||||
int AccessibleInstanceView::logicalIndex(const QModelIndex &index) const
|
||||
int AccessibleInstanceView::logicalIndex(const QModelIndex& index) const
|
||||
{
|
||||
if (!view()->model() || !index.isValid())
|
||||
return -1;
|
||||
return index.row() * (index.model()->columnCount()) + index.column();
|
||||
}
|
||||
|
||||
AccessibleInstanceView::AccessibleInstanceView(QWidget *w)
|
||||
: QAccessibleObject(w)
|
||||
AccessibleInstanceView::AccessibleInstanceView(QWidget* w) : QAccessibleObject(w)
|
||||
{
|
||||
Q_ASSERT(view());
|
||||
}
|
||||
@ -53,7 +51,7 @@ AccessibleInstanceView::~AccessibleInstanceView()
|
||||
}
|
||||
}
|
||||
|
||||
QAccessibleInterface *AccessibleInstanceView::cellAt(int row, int column) const
|
||||
QAccessibleInterface* AccessibleInstanceView::cellAt(int row, int column) const
|
||||
{
|
||||
if (!view()->model()) {
|
||||
return 0;
|
||||
@ -68,7 +66,7 @@ QAccessibleInterface *AccessibleInstanceView::cellAt(int row, int column) const
|
||||
return child(logicalIndex(index));
|
||||
}
|
||||
|
||||
QAccessibleInterface *AccessibleInstanceView::caption() const
|
||||
QAccessibleInterface* AccessibleInstanceView::caption() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@ -123,14 +121,14 @@ QString AccessibleInstanceView::rowDescription(int row) const
|
||||
return view()->model()->headerData(row, Qt::Vertical).toString();
|
||||
}
|
||||
|
||||
QList<QAccessibleInterface *> AccessibleInstanceView::selectedCells() const
|
||||
QList<QAccessibleInterface*> AccessibleInstanceView::selectedCells() const
|
||||
{
|
||||
QList<QAccessibleInterface*> cells;
|
||||
if (!view()->selectionModel())
|
||||
return cells;
|
||||
const QModelIndexList selectedIndexes = view()->selectionModel()->selectedIndexes();
|
||||
cells.reserve(selectedIndexes.size());
|
||||
for (const QModelIndex &index : selectedIndexes)
|
||||
for (const QModelIndex& index : selectedIndexes)
|
||||
cells.append(child(logicalIndex(index)));
|
||||
return cells;
|
||||
}
|
||||
@ -145,7 +143,7 @@ QList<int> AccessibleInstanceView::selectedColumns() const
|
||||
|
||||
QList<int> columns;
|
||||
columns.reserve(selectedColumns.size());
|
||||
for (const QModelIndex &index : selectedColumns) {
|
||||
for (const QModelIndex& index : selectedColumns) {
|
||||
columns.append(index.column());
|
||||
}
|
||||
|
||||
@ -163,14 +161,14 @@ QList<int> AccessibleInstanceView::selectedRows() const
|
||||
const QModelIndexList selectedRows = view()->selectionModel()->selectedRows();
|
||||
|
||||
rows.reserve(selectedRows.size());
|
||||
for (const QModelIndex &index : selectedRows) {
|
||||
for (const QModelIndex& index : selectedRows) {
|
||||
rows.append(index.row());
|
||||
}
|
||||
|
||||
return rows;
|
||||
}
|
||||
|
||||
QAccessibleInterface *AccessibleInstanceView::summary() const
|
||||
QAccessibleInterface* AccessibleInstanceView::summary() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@ -209,16 +207,17 @@ bool AccessibleInstanceView::selectRow(int row)
|
||||
return false;
|
||||
}
|
||||
case QAbstractItemView::SingleSelection: {
|
||||
if (view()->selectionBehavior() != QAbstractItemView::SelectRows && columnCount() > 1 )
|
||||
if (view()->selectionBehavior() != QAbstractItemView::SelectRows && columnCount() > 1)
|
||||
return false;
|
||||
view()->clearSelection();
|
||||
break;
|
||||
}
|
||||
case QAbstractItemView::ContiguousSelection: {
|
||||
if ((!row || !view()->selectionModel()->isRowSelected(row - 1, view()->rootIndex())) && !view()->selectionModel()->isRowSelected(row + 1, view()->rootIndex())) {
|
||||
if ((!row || !view()->selectionModel()->isRowSelected(row - 1, view()->rootIndex())) &&
|
||||
!view()->selectionModel()->isRowSelected(row + 1, view()->rootIndex())) {
|
||||
view()->clearSelection();
|
||||
}
|
||||
break;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
@ -251,7 +250,8 @@ bool AccessibleInstanceView::selectColumn(int column)
|
||||
}
|
||||
/* fallthrough */
|
||||
case QAbstractItemView::ContiguousSelection: {
|
||||
if ((!column || !view()->selectionModel()->isColumnSelected(column - 1, view()->rootIndex())) && !view()->selectionModel()->isColumnSelected(column + 1, view()->rootIndex())) {
|
||||
if ((!column || !view()->selectionModel()->isColumnSelected(column - 1, view()->rootIndex())) &&
|
||||
!view()->selectionModel()->isColumnSelected(column + 1, view()->rootIndex())) {
|
||||
view()->clearSelection();
|
||||
}
|
||||
break;
|
||||
@ -292,10 +292,10 @@ bool AccessibleInstanceView::unselectRow(int row)
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if ((!row || selectionModel->isRowSelected(row - 1, view()->rootIndex())) && selectionModel->isRowSelected(row + 1, view()->rootIndex())) {
|
||||
//If there are rows selected both up the current row and down the current rown,
|
||||
//the ones which are down the current row will be deselected
|
||||
if ((!row || selectionModel->isRowSelected(row - 1, view()->rootIndex())) &&
|
||||
selectionModel->isRowSelected(row + 1, view()->rootIndex())) {
|
||||
// If there are rows selected both up the current row and down the current rown,
|
||||
// the ones which are down the current row will be deselected
|
||||
selection = QItemSelection(index, view()->model()->index(rowCount() - 1, 0, view()->rootIndex()));
|
||||
}
|
||||
}
|
||||
@ -324,8 +324,8 @@ bool AccessibleInstanceView::unselectColumn(int column)
|
||||
|
||||
switch (view()->selectionMode()) {
|
||||
case QAbstractItemView::SingleSelection: {
|
||||
//In SingleSelection and ContiguousSelection once an item
|
||||
//is selected, there's no way for the user to unselect all items
|
||||
// In SingleSelection and ContiguousSelection once an item
|
||||
// is selected, there's no way for the user to unselect all items
|
||||
if (selectedColumnCount() == 1) {
|
||||
return false;
|
||||
}
|
||||
@ -336,10 +336,10 @@ bool AccessibleInstanceView::unselectColumn(int column)
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((!column || view()->selectionModel()->isColumnSelected(column - 1, view()->rootIndex()))
|
||||
&& view()->selectionModel()->isColumnSelected(column + 1, view()->rootIndex())) {
|
||||
//If there are columns selected both at the left of the current row and at the right
|
||||
//of the current row, the ones which are at the right will be deselected
|
||||
if ((!column || view()->selectionModel()->isColumnSelected(column - 1, view()->rootIndex())) &&
|
||||
view()->selectionModel()->isColumnSelected(column + 1, view()->rootIndex())) {
|
||||
// If there are columns selected both at the left of the current row and at the right
|
||||
// of the current row, the ones which are at the right will be deselected
|
||||
selection = QItemSelection(index, model->index(0, columnCount() - 1, view()->rootIndex()));
|
||||
}
|
||||
default:
|
||||
@ -360,9 +360,9 @@ QAccessible::State AccessibleInstanceView::state() const
|
||||
return QAccessible::State();
|
||||
}
|
||||
|
||||
QAccessibleInterface *AccessibleInstanceView::childAt(int x, int y) const
|
||||
QAccessibleInterface* AccessibleInstanceView::childAt(int x, int y) const
|
||||
{
|
||||
QPoint viewportOffset = view()->viewport()->mapTo(view(), QPoint(0,0));
|
||||
QPoint viewportOffset = view()->viewport()->mapTo(view(), QPoint(0, 0));
|
||||
QPoint indexPosition = view()->mapFromGlobal(QPoint(x, y) - viewportOffset);
|
||||
// FIXME: if indexPosition < 0 in one coordinate, return header
|
||||
|
||||
@ -381,22 +381,23 @@ int AccessibleInstanceView::childCount() const
|
||||
return (view()->model()->rowCount()) * (view()->model()->columnCount());
|
||||
}
|
||||
|
||||
int AccessibleInstanceView::indexOfChild(const QAccessibleInterface *iface) const
|
||||
int AccessibleInstanceView::indexOfChild(const QAccessibleInterface* iface) const
|
||||
{
|
||||
if (!view()->model())
|
||||
return -1;
|
||||
QAccessibleInterface *parent = iface->parent();
|
||||
QAccessibleInterface* parent = iface->parent();
|
||||
if (parent->object() != view())
|
||||
return -1;
|
||||
|
||||
Q_ASSERT(iface->role() != QAccessible::TreeItem); // should be handled by tree class
|
||||
Q_ASSERT(iface->role() != QAccessible::TreeItem); // should be handled by tree class
|
||||
if (iface->role() == QAccessible::Cell || iface->role() == QAccessible::ListItem) {
|
||||
const AccessibleInstanceViewItem* cell = static_cast<const AccessibleInstanceViewItem*>(iface);
|
||||
return logicalIndex(cell->m_index);
|
||||
} else if (iface->role() == QAccessible::Pane) {
|
||||
return 0; // corner button
|
||||
return 0; // corner button
|
||||
} else {
|
||||
qWarning() << "AccessibleInstanceView::indexOfChild has a child with unknown role..." << iface->role() << iface->text(QAccessible::Name);
|
||||
qWarning() << "AccessibleInstanceView::indexOfChild has a child with unknown role..." << iface->role()
|
||||
<< iface->text(QAccessible::Name);
|
||||
}
|
||||
// FIXME: we are in denial of our children. this should stop.
|
||||
return -1;
|
||||
@ -417,7 +418,7 @@ QRect AccessibleInstanceView::rect() const
|
||||
return QRect(pos.x(), pos.y(), view()->width(), view()->height());
|
||||
}
|
||||
|
||||
QAccessibleInterface *AccessibleInstanceView::parent() const
|
||||
QAccessibleInterface* AccessibleInstanceView::parent() const
|
||||
{
|
||||
if (view() && view()->parent()) {
|
||||
if (qstrcmp("QComboBoxPrivateContainer", view()->parent()->metaObject()->className()) == 0) {
|
||||
@ -428,7 +429,7 @@ QAccessibleInterface *AccessibleInstanceView::parent() const
|
||||
return 0;
|
||||
}
|
||||
|
||||
QAccessibleInterface *AccessibleInstanceView::child(int logicalIndex) const
|
||||
QAccessibleInterface* AccessibleInstanceView::child(int logicalIndex) const
|
||||
{
|
||||
if (!view()->model())
|
||||
return 0;
|
||||
@ -442,7 +443,7 @@ QAccessibleInterface *AccessibleInstanceView::child(int logicalIndex) const
|
||||
int row = logicalIndex / columns;
|
||||
int column = logicalIndex % columns;
|
||||
|
||||
QAccessibleInterface *iface = 0;
|
||||
QAccessibleInterface* iface = 0;
|
||||
|
||||
QModelIndex index = view()->model()->index(row, column, view()->rootIndex());
|
||||
if (Q_UNLIKELY(!index.isValid())) {
|
||||
@ -456,14 +457,14 @@ QAccessibleInterface *AccessibleInstanceView::child(int logicalIndex) const
|
||||
return iface;
|
||||
}
|
||||
|
||||
void *AccessibleInstanceView::interface_cast(QAccessible::InterfaceType t)
|
||||
void* AccessibleInstanceView::interface_cast(QAccessible::InterfaceType t)
|
||||
{
|
||||
if (t == QAccessible::TableInterface)
|
||||
return static_cast<QAccessibleTableInterface*>(this);
|
||||
return 0;
|
||||
return static_cast<QAccessibleTableInterface*>(this);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void AccessibleInstanceView::modelChange(QAccessibleTableModelChangeEvent *event)
|
||||
void AccessibleInstanceView::modelChange(QAccessibleTableModelChangeEvent* event)
|
||||
{
|
||||
// if there is no cache yet, we don't update anything
|
||||
if (childToId.isEmpty())
|
||||
@ -479,13 +480,12 @@ void AccessibleInstanceView::modelChange(QAccessibleTableModelChangeEvent *event
|
||||
// rows are inserted: move every row after that
|
||||
case QAccessibleTableModelChangeEvent::RowsInserted:
|
||||
case QAccessibleTableModelChangeEvent::ColumnsInserted: {
|
||||
|
||||
ChildCache newCache;
|
||||
ChildCache::ConstIterator iter = childToId.constBegin();
|
||||
|
||||
while (iter != childToId.constEnd()) {
|
||||
QAccessible::Id id = iter.value();
|
||||
QAccessibleInterface *iface = QAccessible::accessibleInterface(id);
|
||||
QAccessibleInterface* iface = QAccessible::accessibleInterface(id);
|
||||
Q_ASSERT(iface);
|
||||
if (indexOfChild(iface) >= 0) {
|
||||
newCache.insert(indexOfChild(iface), id);
|
||||
@ -507,11 +507,11 @@ void AccessibleInstanceView::modelChange(QAccessibleTableModelChangeEvent *event
|
||||
ChildCache::ConstIterator iter = childToId.constBegin();
|
||||
while (iter != childToId.constEnd()) {
|
||||
QAccessible::Id id = iter.value();
|
||||
QAccessibleInterface *iface = QAccessible::accessibleInterface(id);
|
||||
QAccessibleInterface* iface = QAccessible::accessibleInterface(id);
|
||||
Q_ASSERT(iface);
|
||||
if (iface->role() == QAccessible::Cell || iface->role() == QAccessible::ListItem) {
|
||||
Q_ASSERT(iface->tableCellInterface());
|
||||
AccessibleInstanceViewItem *cell = static_cast<AccessibleInstanceViewItem*>(iface->tableCellInterface());
|
||||
AccessibleInstanceViewItem* cell = static_cast<AccessibleInstanceViewItem*>(iface->tableCellInterface());
|
||||
// Since it is a QPersistentModelIndex, we only need to check if it is valid
|
||||
if (cell->m_index.isValid())
|
||||
newCache.insert(indexOfChild(cell), id);
|
||||
@ -532,14 +532,13 @@ void AccessibleInstanceView::modelChange(QAccessibleTableModelChangeEvent *event
|
||||
|
||||
// TABLE CELL
|
||||
|
||||
AccessibleInstanceViewItem::AccessibleInstanceViewItem(QAbstractItemView *view_, const QModelIndex &index_)
|
||||
: view(view_), m_index(index_)
|
||||
AccessibleInstanceViewItem::AccessibleInstanceViewItem(QAbstractItemView* view_, const QModelIndex& index_) : view(view_), m_index(index_)
|
||||
{
|
||||
if (Q_UNLIKELY(!index_.isValid()))
|
||||
qWarning() << "AccessibleInstanceViewItem::AccessibleInstanceViewItem with invalid index: " << index_;
|
||||
}
|
||||
|
||||
void *AccessibleInstanceViewItem::interface_cast(QAccessible::InterfaceType t)
|
||||
void* AccessibleInstanceViewItem::interface_cast(QAccessible::InterfaceType t)
|
||||
{
|
||||
if (t == QAccessible::TableCellInterface)
|
||||
return static_cast<QAccessibleTableCellInterface*>(this);
|
||||
@ -548,8 +547,14 @@ void *AccessibleInstanceViewItem::interface_cast(QAccessible::InterfaceType t)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int AccessibleInstanceViewItem::columnExtent() const { return 1; }
|
||||
int AccessibleInstanceViewItem::rowExtent() const { return 1; }
|
||||
int AccessibleInstanceViewItem::columnExtent() const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
int AccessibleInstanceViewItem::rowExtent() const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
QList<QAccessibleInterface*> AccessibleInstanceViewItem::rowHeaderCells() const
|
||||
{
|
||||
@ -600,19 +605,17 @@ void AccessibleInstanceViewItem::doAction(const QString& actionName)
|
||||
if (actionName == toggleAction()) {
|
||||
if (isSelected()) {
|
||||
unselectCell();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
selectCell();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QStringList AccessibleInstanceViewItem::keyBindingsForAction(const QString &) const
|
||||
QStringList AccessibleInstanceViewItem::keyBindingsForAction(const QString&) const
|
||||
{
|
||||
return QStringList();
|
||||
}
|
||||
|
||||
|
||||
void AccessibleInstanceViewItem::selectCell()
|
||||
{
|
||||
if (!isValid()) {
|
||||
@ -624,7 +627,7 @@ void AccessibleInstanceViewItem::selectCell()
|
||||
}
|
||||
|
||||
Q_ASSERT(table());
|
||||
QAccessibleTableInterface *cellTable = table()->tableInterface();
|
||||
QAccessibleTableInterface* cellTable = table()->tableInterface();
|
||||
|
||||
switch (view->selectionBehavior()) {
|
||||
case QAbstractItemView::SelectItems:
|
||||
@ -654,7 +657,7 @@ void AccessibleInstanceViewItem::unselectCell()
|
||||
if (selectionMode == QAbstractItemView::NoSelection)
|
||||
return;
|
||||
|
||||
QAccessibleTableInterface *cellTable = table()->tableInterface();
|
||||
QAccessibleTableInterface* cellTable = table()->tableInterface();
|
||||
|
||||
switch (view->selectionBehavior()) {
|
||||
case QAbstractItemView::SelectItems:
|
||||
@ -669,15 +672,16 @@ void AccessibleInstanceViewItem::unselectCell()
|
||||
return;
|
||||
}
|
||||
|
||||
//If the mode is not MultiSelection or ExtendedSelection and only
|
||||
//one cell is selected it cannot be unselected by the user
|
||||
if ((selectionMode != QAbstractItemView::MultiSelection) && (selectionMode != QAbstractItemView::ExtendedSelection) && (view->selectionModel()->selectedIndexes().count() <= 1))
|
||||
// If the mode is not MultiSelection or ExtendedSelection and only
|
||||
// one cell is selected it cannot be unselected by the user
|
||||
if ((selectionMode != QAbstractItemView::MultiSelection) && (selectionMode != QAbstractItemView::ExtendedSelection) &&
|
||||
(view->selectionModel()->selectedIndexes().count() <= 1))
|
||||
return;
|
||||
|
||||
view->selectionModel()->select(m_index, QItemSelectionModel::Deselect);
|
||||
}
|
||||
|
||||
QAccessibleInterface *AccessibleInstanceViewItem::table() const
|
||||
QAccessibleInterface* AccessibleInstanceViewItem::table() const
|
||||
{
|
||||
return QAccessible::queryAccessibleInterface(view);
|
||||
}
|
||||
@ -694,7 +698,7 @@ QAccessible::State AccessibleInstanceViewItem::state() const
|
||||
return st;
|
||||
|
||||
QRect globalRect = view->rect();
|
||||
globalRect.translate(view->mapToGlobal(QPoint(0,0)));
|
||||
globalRect.translate(view->mapToGlobal(QPoint(0, 0)));
|
||||
if (!globalRect.intersects(rect()))
|
||||
st.invisible = true;
|
||||
|
||||
@ -717,7 +721,6 @@ QAccessible::State AccessibleInstanceViewItem::state() const
|
||||
return st;
|
||||
}
|
||||
|
||||
|
||||
QRect AccessibleInstanceViewItem::rect() const
|
||||
{
|
||||
QRect r;
|
||||
@ -726,7 +729,7 @@ QRect AccessibleInstanceViewItem::rect() const
|
||||
r = view->visualRect(m_index);
|
||||
|
||||
if (!r.isNull()) {
|
||||
r.translate(view->viewport()->mapTo(view, QPoint(0,0)));
|
||||
r.translate(view->viewport()->mapTo(view, QPoint(0, 0)));
|
||||
r.translate(view->mapToGlobal(QPoint(0, 0)));
|
||||
}
|
||||
return r;
|
||||
@ -737,7 +740,7 @@ QString AccessibleInstanceViewItem::text(QAccessible::Text t) const
|
||||
QString value;
|
||||
if (!isValid())
|
||||
return value;
|
||||
QAbstractItemModel *model = view->model();
|
||||
QAbstractItemModel* model = view->model();
|
||||
switch (t) {
|
||||
case QAccessible::Name:
|
||||
value = model->data(m_index, Qt::AccessibleTextRole).toString();
|
||||
@ -753,7 +756,7 @@ QString AccessibleInstanceViewItem::text(QAccessible::Text t) const
|
||||
return value;
|
||||
}
|
||||
|
||||
void AccessibleInstanceViewItem::setText(QAccessible::Text /*t*/, const QString &text)
|
||||
void AccessibleInstanceViewItem::setText(QAccessible::Text /*t*/, const QString& text)
|
||||
{
|
||||
if (!isValid() || !(m_index.flags() & Qt::ItemIsEditable))
|
||||
return;
|
||||
@ -765,12 +768,12 @@ bool AccessibleInstanceViewItem::isValid() const
|
||||
return view && view->model() && m_index.isValid();
|
||||
}
|
||||
|
||||
QAccessibleInterface *AccessibleInstanceViewItem::parent() const
|
||||
QAccessibleInterface* AccessibleInstanceViewItem::parent() const
|
||||
{
|
||||
return QAccessible::queryAccessibleInterface(view);
|
||||
}
|
||||
|
||||
QAccessibleInterface *AccessibleInstanceViewItem::child(int) const
|
||||
QAccessibleInterface* AccessibleInstanceViewItem::child(int) const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
class QAccessibleInterface;
|
||||
|
||||
QAccessibleInterface *groupViewAccessibleFactory(const QString &classname, QObject *object);
|
||||
QAccessibleInterface* groupViewAccessibleFactory(const QString& classname, QObject* object);
|
||||
|
@ -1,9 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "QtCore/qpointer.h"
|
||||
#include <QtGui/qaccessible.h>
|
||||
#include <QAccessibleWidget>
|
||||
#include <QAbstractItemView>
|
||||
#include <QAccessibleWidget>
|
||||
#include "QtCore/qpointer.h"
|
||||
#ifndef QT_NO_ACCESSIBILITY
|
||||
#include "InstanceView.h"
|
||||
// #include <QHeaderView>
|
||||
@ -11,10 +11,9 @@
|
||||
class QAccessibleTableCell;
|
||||
class QAccessibleTableHeaderCell;
|
||||
|
||||
class AccessibleInstanceView :public QAccessibleTableInterface, public QAccessibleObject
|
||||
{
|
||||
public:
|
||||
explicit AccessibleInstanceView(QWidget *w);
|
||||
class AccessibleInstanceView : public QAccessibleTableInterface, public QAccessibleObject {
|
||||
public:
|
||||
explicit AccessibleInstanceView(QWidget* w);
|
||||
bool isValid() const override;
|
||||
|
||||
QAccessible::Role role() const override;
|
||||
@ -22,19 +21,19 @@ public:
|
||||
QString text(QAccessible::Text t) const override;
|
||||
QRect rect() const override;
|
||||
|
||||
QAccessibleInterface *childAt(int x, int y) const override;
|
||||
QAccessibleInterface* childAt(int x, int y) const override;
|
||||
int childCount() const override;
|
||||
int indexOfChild(const QAccessibleInterface *) const override;
|
||||
int indexOfChild(const QAccessibleInterface*) const override;
|
||||
|
||||
QAccessibleInterface *parent() const override;
|
||||
QAccessibleInterface *child(int index) const override;
|
||||
QAccessibleInterface* parent() const override;
|
||||
QAccessibleInterface* child(int index) const override;
|
||||
|
||||
void *interface_cast(QAccessible::InterfaceType t) override;
|
||||
void* interface_cast(QAccessible::InterfaceType t) override;
|
||||
|
||||
// table interface
|
||||
QAccessibleInterface *cellAt(int row, int column) const override;
|
||||
QAccessibleInterface *caption() const override;
|
||||
QAccessibleInterface *summary() const override;
|
||||
QAccessibleInterface* cellAt(int row, int column) const override;
|
||||
QAccessibleInterface* caption() const override;
|
||||
QAccessibleInterface* summary() const override;
|
||||
QString columnDescription(int column) const override;
|
||||
QString rowDescription(int row) const override;
|
||||
int columnCount() const override;
|
||||
@ -54,42 +53,41 @@ public:
|
||||
bool unselectRow(int row) override;
|
||||
bool unselectColumn(int column) override;
|
||||
|
||||
QAbstractItemView *view() const;
|
||||
QAbstractItemView* view() const;
|
||||
|
||||
void modelChange(QAccessibleTableModelChangeEvent *event) override;
|
||||
void modelChange(QAccessibleTableModelChangeEvent* event) override;
|
||||
|
||||
protected:
|
||||
protected:
|
||||
// maybe vector
|
||||
typedef QHash<int, QAccessible::Id> ChildCache;
|
||||
mutable ChildCache childToId;
|
||||
|
||||
virtual ~AccessibleInstanceView();
|
||||
|
||||
private:
|
||||
inline int logicalIndex(const QModelIndex &index) const;
|
||||
private:
|
||||
inline int logicalIndex(const QModelIndex& index) const;
|
||||
};
|
||||
|
||||
class AccessibleInstanceViewItem: public QAccessibleInterface, public QAccessibleTableCellInterface, public QAccessibleActionInterface
|
||||
{
|
||||
public:
|
||||
AccessibleInstanceViewItem(QAbstractItemView *view, const QModelIndex &m_index);
|
||||
class AccessibleInstanceViewItem : public QAccessibleInterface, public QAccessibleTableCellInterface, public QAccessibleActionInterface {
|
||||
public:
|
||||
AccessibleInstanceViewItem(QAbstractItemView* view, const QModelIndex& m_index);
|
||||
|
||||
void *interface_cast(QAccessible::InterfaceType t) override;
|
||||
QObject *object() const override { return nullptr; }
|
||||
void* interface_cast(QAccessible::InterfaceType t) override;
|
||||
QObject* object() const override { return nullptr; }
|
||||
QAccessible::Role role() const override;
|
||||
QAccessible::State state() const override;
|
||||
QRect rect() const override;
|
||||
bool isValid() const override;
|
||||
|
||||
QAccessibleInterface *childAt(int, int) const override { return nullptr; }
|
||||
QAccessibleInterface* childAt(int, int) const override { return nullptr; }
|
||||
int childCount() const override { return 0; }
|
||||
int indexOfChild(const QAccessibleInterface *) const override { return -1; }
|
||||
int indexOfChild(const QAccessibleInterface*) const override { return -1; }
|
||||
|
||||
QString text(QAccessible::Text t) const override;
|
||||
void setText(QAccessible::Text t, const QString &text) override;
|
||||
void setText(QAccessible::Text t, const QString& text) override;
|
||||
|
||||
QAccessibleInterface *parent() const override;
|
||||
QAccessibleInterface *child(int) const override;
|
||||
QAccessibleInterface* parent() const override;
|
||||
QAccessibleInterface* child(int) const override;
|
||||
|
||||
// cell interface
|
||||
int columnExtent() const override;
|
||||
@ -101,13 +99,13 @@ public:
|
||||
bool isSelected() const override;
|
||||
QAccessibleInterface* table() const override;
|
||||
|
||||
//action interface
|
||||
// action interface
|
||||
QStringList actionNames() const override;
|
||||
void doAction(const QString &actionName) override;
|
||||
QStringList keyBindingsForAction(const QString &actionName) const override;
|
||||
void doAction(const QString& actionName) override;
|
||||
QStringList keyBindingsForAction(const QString& actionName) const override;
|
||||
|
||||
private:
|
||||
QPointer<QAbstractItemView > view;
|
||||
private:
|
||||
QPointer<QAbstractItemView> view;
|
||||
QPersistentModelIndex m_index;
|
||||
|
||||
void selectCell();
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
/*
|
||||
* PolyMC - Minecraft Launcher
|
||||
* Prism Launcher - Minecraft Launcher
|
||||
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
@ -34,29 +34,27 @@
|
||||
*/
|
||||
|
||||
#include "InstanceDelegate.h"
|
||||
#include <QPainter>
|
||||
#include <QTextOption>
|
||||
#include <QTextLayout>
|
||||
#include <QApplication>
|
||||
#include <QtMath>
|
||||
#include <QDebug>
|
||||
#include <QPainter>
|
||||
#include <QTextLayout>
|
||||
#include <QTextOption>
|
||||
#include <QtMath>
|
||||
|
||||
#include "InstanceView.h"
|
||||
#include "BaseInstance.h"
|
||||
#include "InstanceList.h"
|
||||
#include <QIcon>
|
||||
#include <QTextEdit>
|
||||
#include "BaseInstance.h"
|
||||
#include "InstanceList.h"
|
||||
#include "InstanceView.h"
|
||||
|
||||
// Origin: Qt
|
||||
static void viewItemTextLayout(QTextLayout &textLayout, int lineWidth, qreal &height,
|
||||
qreal &widthUsed)
|
||||
static void viewItemTextLayout(QTextLayout& textLayout, int lineWidth, qreal& height, qreal& widthUsed)
|
||||
{
|
||||
height = 0;
|
||||
widthUsed = 0;
|
||||
textLayout.beginLayout();
|
||||
QString str = textLayout.text();
|
||||
while (true)
|
||||
{
|
||||
while (true) {
|
||||
QTextLine line = textLayout.createLine();
|
||||
if (!line.isValid())
|
||||
break;
|
||||
@ -70,24 +68,20 @@ static void viewItemTextLayout(QTextLayout &textLayout, int lineWidth, qreal &he
|
||||
textLayout.endLayout();
|
||||
}
|
||||
|
||||
ListViewDelegate::ListViewDelegate(QObject *parent) : QStyledItemDelegate(parent)
|
||||
{
|
||||
}
|
||||
ListViewDelegate::ListViewDelegate(QObject* parent) : QStyledItemDelegate(parent) {}
|
||||
|
||||
void drawSelectionRect(QPainter *painter, const QStyleOptionViewItem &option,
|
||||
const QRect &rect)
|
||||
void drawSelectionRect(QPainter* painter, const QStyleOptionViewItem& option, const QRect& rect)
|
||||
{
|
||||
if ((option.state & QStyle::State_Selected))
|
||||
painter->fillRect(rect, option.palette.brush(QPalette::Highlight));
|
||||
else
|
||||
{
|
||||
else {
|
||||
QColor backgroundColor = option.palette.color(QPalette::Window);
|
||||
backgroundColor.setAlpha(160);
|
||||
painter->fillRect(rect, QBrush(backgroundColor));
|
||||
}
|
||||
}
|
||||
|
||||
void drawFocusRect(QPainter *painter, const QStyleOptionViewItem &option, const QRect &rect)
|
||||
void drawFocusRect(QPainter* painter, const QStyleOptionViewItem& option, const QRect& rect)
|
||||
{
|
||||
if (!(option.state & QStyle::State_HasFocus))
|
||||
return;
|
||||
@ -103,7 +97,7 @@ void drawFocusRect(QPainter *painter, const QStyleOptionViewItem &option, const
|
||||
// Apparently some widget styles expect this hint to not be set
|
||||
painter->setRenderHint(QPainter::Antialiasing, false);
|
||||
|
||||
QStyle *style = option.widget ? option.widget->style() : QApplication::style();
|
||||
QStyle* style = option.widget ? option.widget->style() : QApplication::style();
|
||||
|
||||
style->drawPrimitive(QStyle::PE_FrameFocusRect, &opt, painter, option.widget);
|
||||
|
||||
@ -111,11 +105,9 @@ void drawFocusRect(QPainter *painter, const QStyleOptionViewItem &option, const
|
||||
}
|
||||
|
||||
// TODO this can be made a lot prettier
|
||||
void drawProgressOverlay(QPainter *painter, const QStyleOptionViewItem &option,
|
||||
const int value, const int maximum)
|
||||
void drawProgressOverlay(QPainter* painter, const QStyleOptionViewItem& option, const int value, const int maximum)
|
||||
{
|
||||
if (maximum == 0 || value == maximum)
|
||||
{
|
||||
if (maximum == 0 || value == maximum) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -131,19 +123,15 @@ void drawProgressOverlay(QPainter *painter, const QStyleOptionViewItem &option,
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
void drawBadges(QPainter *painter, const QStyleOptionViewItem &option, BaseInstance *instance, QIcon::Mode mode, QIcon::State state)
|
||||
void drawBadges(QPainter* painter, const QStyleOptionViewItem& option, BaseInstance* instance, QIcon::Mode mode, QIcon::State state)
|
||||
{
|
||||
QList<QString> pixmaps;
|
||||
if (instance->isRunning())
|
||||
{
|
||||
if (instance->isRunning()) {
|
||||
pixmaps.append("status-running");
|
||||
}
|
||||
else if (instance->hasCrashed() || instance->hasVersionBroken())
|
||||
{
|
||||
} else if (instance->hasCrashed() || instance->hasVersionBroken()) {
|
||||
pixmaps.append("status-bad");
|
||||
}
|
||||
if (instance->hasUpdateAvailable())
|
||||
{
|
||||
if (instance->hasUpdateAvailable()) {
|
||||
pixmaps.append("checkupdate");
|
||||
}
|
||||
|
||||
@ -153,12 +141,9 @@ void drawBadges(QPainter *painter, const QStyleOptionViewItem &option, BaseInsta
|
||||
const int rows = qCeil((double)pixmaps.size() / (double)itemsPerRow);
|
||||
QListIterator<QString> it(pixmaps);
|
||||
painter->translate(option.rect.topLeft());
|
||||
for (int y = 0; y < rows; ++y)
|
||||
{
|
||||
for (int x = 0; x < itemsPerRow; ++x)
|
||||
{
|
||||
if (!it.hasNext())
|
||||
{
|
||||
for (int y = 0; y < rows; ++y) {
|
||||
for (int x = 0; x < itemsPerRow; ++x) {
|
||||
if (!it.hasNext()) {
|
||||
return;
|
||||
}
|
||||
// FIXME: inject this.
|
||||
@ -166,21 +151,17 @@ void drawBadges(QPainter *painter, const QStyleOptionViewItem &option, BaseInsta
|
||||
// opt.icon.paint(painter, iconbox, Qt::AlignCenter, mode, state);
|
||||
const QPixmap pixmap;
|
||||
// itemSide
|
||||
QRect badgeRect(
|
||||
option.rect.width() - x * itemSide + qMax(x - 1, 0) * spacing - itemSide,
|
||||
y * itemSide + qMax(y - 1, 0) * spacing,
|
||||
itemSide,
|
||||
itemSide
|
||||
);
|
||||
QRect badgeRect(option.rect.width() - x * itemSide + qMax(x - 1, 0) * spacing - itemSide,
|
||||
y * itemSide + qMax(y - 1, 0) * spacing, itemSide, itemSide);
|
||||
icon.paint(painter, badgeRect, Qt::AlignCenter, mode, state);
|
||||
}
|
||||
}
|
||||
painter->translate(-option.rect.topLeft());
|
||||
}
|
||||
|
||||
static QSize viewItemTextSize(const QStyleOptionViewItem *option)
|
||||
static QSize viewItemTextSize(const QStyleOptionViewItem* option)
|
||||
{
|
||||
QStyle *style = option->widget ? option->widget->style() : QApplication::style();
|
||||
QStyle* style = option->widget ? option->widget->style() : QApplication::style();
|
||||
QTextOption textOption;
|
||||
textOption.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
|
||||
QTextLayout textLayout;
|
||||
@ -195,8 +176,7 @@ static QSize viewItemTextSize(const QStyleOptionViewItem *option)
|
||||
return QSize(size.width() + 2 * textMargin, size.height());
|
||||
}
|
||||
|
||||
void ListViewDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const
|
||||
void ListViewDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
|
||||
{
|
||||
QStyleOptionViewItem opt = option;
|
||||
initStyleOption(&opt, index);
|
||||
@ -208,7 +188,7 @@ void ListViewDelegate::paint(QPainter *painter, const QStyleOptionViewItem &opti
|
||||
opt.textElideMode = Qt::ElideRight;
|
||||
opt.displayAlignment = Qt::AlignTop | Qt::AlignHCenter;
|
||||
|
||||
QStyle *style = opt.widget ? opt.widget->style() : QApplication::style();
|
||||
QStyle* style = opt.widget ? opt.widget->style() : QApplication::style();
|
||||
|
||||
// const int iconSize = style->pixelMetric(QStyle::PM_IconViewIconSize);
|
||||
const int iconSize = 48;
|
||||
@ -296,16 +276,12 @@ void ListViewDelegate::paint(QPainter *painter, const QStyleOptionViewItem &opti
|
||||
opt.icon.paint(painter, iconbox, Qt::AlignCenter, mode, state);
|
||||
}
|
||||
// set the text colors
|
||||
QPalette::ColorGroup cg =
|
||||
opt.state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled;
|
||||
QPalette::ColorGroup cg = opt.state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled;
|
||||
if (cg == QPalette::Normal && !(opt.state & QStyle::State_Active))
|
||||
cg = QPalette::Inactive;
|
||||
if (opt.state & QStyle::State_Selected)
|
||||
{
|
||||
if (opt.state & QStyle::State_Selected) {
|
||||
painter->setPen(opt.palette.color(cg, QPalette::HighlightedText));
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
painter->setPen(opt.palette.color(cg, QPalette::Text));
|
||||
}
|
||||
|
||||
@ -324,20 +300,16 @@ void ListViewDelegate::paint(QPainter *painter, const QStyleOptionViewItem &opti
|
||||
|
||||
const int lineCount = textLayout.lineCount();
|
||||
|
||||
const QRect layoutRect = QStyle::alignedRect(
|
||||
opt.direction, opt.displayAlignment, QSize(textRect.width(), int(height)), textRect);
|
||||
const QRect layoutRect = QStyle::alignedRect(opt.direction, opt.displayAlignment, QSize(textRect.width(), int(height)), textRect);
|
||||
const QPointF position = layoutRect.topLeft();
|
||||
for (int i = 0; i < lineCount; ++i)
|
||||
{
|
||||
for (int i = 0; i < lineCount; ++i) {
|
||||
const QTextLine line = textLayout.lineAt(i);
|
||||
line.draw(painter, position);
|
||||
}
|
||||
|
||||
// FIXME: this really has no business of being here. Make generic.
|
||||
auto instance = (BaseInstance*)index.data(InstanceList::InstancePointerRole)
|
||||
.value<void *>();
|
||||
if (instance)
|
||||
{
|
||||
auto instance = (BaseInstance*)index.data(InstanceList::InstancePointerRole).value<void*>();
|
||||
if (instance) {
|
||||
drawBadges(painter, opt, instance, mode, state);
|
||||
}
|
||||
|
||||
@ -347,8 +319,7 @@ void ListViewDelegate::paint(QPainter *painter, const QStyleOptionViewItem &opti
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
QSize ListViewDelegate::sizeHint(const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const
|
||||
QSize ListViewDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const
|
||||
{
|
||||
QStyleOptionViewItem opt = option;
|
||||
initStyleOption(&opt, index);
|
||||
@ -357,9 +328,9 @@ QSize ListViewDelegate::sizeHint(const QStyleOptionViewItem &option,
|
||||
opt.textElideMode = Qt::ElideRight;
|
||||
opt.displayAlignment = Qt::AlignTop | Qt::AlignHCenter;
|
||||
|
||||
QStyle *style = opt.widget ? opt.widget->style() : QApplication::style();
|
||||
QStyle* style = opt.widget ? opt.widget->style() : QApplication::style();
|
||||
const int textMargin = style->pixelMetric(QStyle::PM_FocusFrameHMargin, &option, opt.widget) + 1;
|
||||
int height = 48 + textMargin * 2 + 5; // TODO: turn constants into variables
|
||||
int height = 48 + textMargin * 2 + 5; // TODO: turn constants into variables
|
||||
QSize szz = viewItemTextSize(&opt);
|
||||
height += szz.height();
|
||||
// FIXME: maybe the icon items could scale and keep proportions?
|
||||
@ -367,36 +338,32 @@ QSize ListViewDelegate::sizeHint(const QStyleOptionViewItem &option,
|
||||
return sz;
|
||||
}
|
||||
|
||||
class NoReturnTextEdit: public QTextEdit
|
||||
{
|
||||
class NoReturnTextEdit : public QTextEdit {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit NoReturnTextEdit(QWidget *parent) : QTextEdit(parent)
|
||||
public:
|
||||
explicit NoReturnTextEdit(QWidget* parent) : QTextEdit(parent)
|
||||
{
|
||||
setTextInteractionFlags(Qt::TextEditorInteraction);
|
||||
setHorizontalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAlwaysOff);
|
||||
setVerticalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAlwaysOff);
|
||||
}
|
||||
bool event(QEvent * event) override
|
||||
bool event(QEvent* event) override
|
||||
{
|
||||
auto eventType = event->type();
|
||||
if(eventType == QEvent::KeyPress || eventType == QEvent::KeyRelease)
|
||||
{
|
||||
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
|
||||
if (eventType == QEvent::KeyPress || eventType == QEvent::KeyRelease) {
|
||||
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
|
||||
auto key = keyEvent->key();
|
||||
if ((key == Qt::Key_Return || key == Qt::Key_Enter) && eventType == QEvent::KeyPress)
|
||||
{
|
||||
if ((key == Qt::Key_Return || key == Qt::Key_Enter) && eventType == QEvent::KeyPress) {
|
||||
emit editingDone();
|
||||
return true;
|
||||
}
|
||||
if(key == Qt::Key_Tab)
|
||||
{
|
||||
if (key == Qt::Key_Tab) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return QTextEdit::event(event);
|
||||
}
|
||||
signals:
|
||||
signals:
|
||||
void editingDone();
|
||||
};
|
||||
|
||||
@ -412,7 +379,7 @@ void ListViewDelegate::updateEditorGeometry(QWidget* editor, const QStyleOptionV
|
||||
void ListViewDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const
|
||||
{
|
||||
auto text = index.data(Qt::EditRole).toString();
|
||||
QTextEdit * realeditor = qobject_cast<NoReturnTextEdit *>(editor);
|
||||
QTextEdit* realeditor = qobject_cast<NoReturnTextEdit*>(editor);
|
||||
realeditor->setAlignment(Qt::AlignHCenter | Qt::AlignTop);
|
||||
realeditor->append(text);
|
||||
realeditor->selectAll();
|
||||
@ -421,19 +388,18 @@ void ListViewDelegate::setEditorData(QWidget* editor, const QModelIndex& index)
|
||||
|
||||
void ListViewDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const
|
||||
{
|
||||
QTextEdit * realeditor = qobject_cast<NoReturnTextEdit *>(editor);
|
||||
QTextEdit* realeditor = qobject_cast<NoReturnTextEdit*>(editor);
|
||||
QString text = realeditor->toPlainText();
|
||||
text.replace(QChar('\n'), QChar(' '));
|
||||
text = text.trimmed();
|
||||
// Prevent instance names longer than 128 chars
|
||||
text.truncate(128);
|
||||
if(text.size() != 0)
|
||||
{
|
||||
if (text.size() != 0) {
|
||||
model->setData(index, text);
|
||||
}
|
||||
}
|
||||
|
||||
QWidget * ListViewDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const
|
||||
QWidget* ListViewDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const
|
||||
{
|
||||
auto editor = new NoReturnTextEdit(parent);
|
||||
connect(editor, &NoReturnTextEdit::editingDone, this, &ListViewDelegate::editingDone);
|
||||
@ -442,7 +408,7 @@ QWidget * ListViewDelegate::createEditor(QWidget* parent, const QStyleOptionView
|
||||
|
||||
void ListViewDelegate::editingDone()
|
||||
{
|
||||
NoReturnTextEdit *editor = qobject_cast<NoReturnTextEdit *>(sender());
|
||||
NoReturnTextEdit* editor = qobject_cast<NoReturnTextEdit*>(sender());
|
||||
emit commitData(editor);
|
||||
emit closeEditor(editor);
|
||||
}
|
||||
|
@ -15,25 +15,24 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QStyledItemDelegate>
|
||||
#include <QCache>
|
||||
#include <QStyledItemDelegate>
|
||||
|
||||
class ListViewDelegate : public QStyledItemDelegate
|
||||
{
|
||||
class ListViewDelegate : public QStyledItemDelegate {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ListViewDelegate(QObject *parent = 0);
|
||||
public:
|
||||
explicit ListViewDelegate(QObject* parent = 0);
|
||||
virtual ~ListViewDelegate() {}
|
||||
|
||||
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
|
||||
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override;
|
||||
void updateEditorGeometry(QWidget * editor, const QStyleOptionViewItem & option, const QModelIndex & index) const override;
|
||||
QWidget * createEditor(QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index) const override;
|
||||
void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override;
|
||||
QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const override;
|
||||
void updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const override;
|
||||
QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const override;
|
||||
|
||||
void setEditorData(QWidget * editor, const QModelIndex & index) const override;
|
||||
void setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const override;
|
||||
void setEditorData(QWidget* editor, const QModelIndex& index) const override;
|
||||
void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const override;
|
||||
|
||||
private slots:
|
||||
private slots:
|
||||
void editingDone();
|
||||
};
|
||||
|
@ -15,57 +15,54 @@
|
||||
|
||||
#include "InstanceProxyModel.h"
|
||||
|
||||
#include "InstanceView.h"
|
||||
#include "Application.h"
|
||||
#include <BaseInstance.h>
|
||||
#include <icons/IconList.h>
|
||||
#include "Application.h"
|
||||
#include "InstanceView.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
InstanceProxyModel::InstanceProxyModel(QObject *parent) : QSortFilterProxyModel(parent) {
|
||||
InstanceProxyModel::InstanceProxyModel(QObject* parent) : QSortFilterProxyModel(parent)
|
||||
{
|
||||
m_naturalSort.setNumericMode(true);
|
||||
m_naturalSort.setCaseSensitivity(Qt::CaseSensitivity::CaseInsensitive);
|
||||
// FIXME: use loaded translation as source of locale instead, hook this up to translation changes
|
||||
m_naturalSort.setLocale(QLocale::system());
|
||||
}
|
||||
|
||||
QVariant InstanceProxyModel::data(const QModelIndex & index, int role) const
|
||||
QVariant InstanceProxyModel::data(const QModelIndex& index, int role) const
|
||||
{
|
||||
QVariant data = QSortFilterProxyModel::data(index, role);
|
||||
if(role == Qt::DecorationRole)
|
||||
{
|
||||
if (role == Qt::DecorationRole) {
|
||||
return QVariant(APPLICATION->icons()->getIcon(data.toString()));
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
bool InstanceProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const {
|
||||
bool InstanceProxyModel::lessThan(const QModelIndex& left, const QModelIndex& right) const
|
||||
{
|
||||
const QString leftCategory = left.data(InstanceViewRoles::GroupRole).toString();
|
||||
const QString rightCategory = right.data(InstanceViewRoles::GroupRole).toString();
|
||||
if (leftCategory == rightCategory) {
|
||||
return subSortLessThan(left, right);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// FIXME: real group sorting happens in InstanceView::updateGeometries(), see LocaleString
|
||||
auto result = leftCategory.localeAwareCompare(rightCategory);
|
||||
if(result == 0) {
|
||||
if (result == 0) {
|
||||
return subSortLessThan(left, right);
|
||||
}
|
||||
return result < 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool InstanceProxyModel::subSortLessThan(const QModelIndex &left, const QModelIndex &right) const
|
||||
bool InstanceProxyModel::subSortLessThan(const QModelIndex& left, const QModelIndex& right) const
|
||||
{
|
||||
BaseInstance *pdataLeft = static_cast<BaseInstance *>(left.internalPointer());
|
||||
BaseInstance *pdataRight = static_cast<BaseInstance *>(right.internalPointer());
|
||||
BaseInstance* pdataLeft = static_cast<BaseInstance*>(left.internalPointer());
|
||||
BaseInstance* pdataRight = static_cast<BaseInstance*>(right.internalPointer());
|
||||
QString sortMode = APPLICATION->settings()->get("InstSortMode").toString();
|
||||
if (sortMode == "LastLaunch")
|
||||
{
|
||||
if (sortMode == "LastLaunch") {
|
||||
return pdataLeft->lastLaunch() > pdataRight->lastLaunch();
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return m_naturalSort.compare(pdataLeft->name(), pdataRight->name()) < 0;
|
||||
}
|
||||
}
|
||||
|
@ -15,21 +15,20 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QSortFilterProxyModel>
|
||||
#include <QCollator>
|
||||
#include <QSortFilterProxyModel>
|
||||
|
||||
class InstanceProxyModel : public QSortFilterProxyModel
|
||||
{
|
||||
class InstanceProxyModel : public QSortFilterProxyModel {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
InstanceProxyModel(QObject *parent = 0);
|
||||
public:
|
||||
InstanceProxyModel(QObject* parent = 0);
|
||||
|
||||
protected:
|
||||
QVariant data(const QModelIndex & index, int role) const override;
|
||||
bool lessThan(const QModelIndex &left, const QModelIndex &right) const override;
|
||||
bool subSortLessThan(const QModelIndex &left, const QModelIndex &right) const;
|
||||
protected:
|
||||
QVariant data(const QModelIndex& index, int role) const override;
|
||||
bool lessThan(const QModelIndex& left, const QModelIndex& right) const override;
|
||||
bool subSortLessThan(const QModelIndex& left, const QModelIndex& right) const;
|
||||
|
||||
private:
|
||||
private:
|
||||
QCollator m_naturalSort;
|
||||
};
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
/*
|
||||
* PolyMC - Minecraft Launcher
|
||||
* Prism Launcher - Minecraft Launcher
|
||||
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
@ -49,10 +49,7 @@
|
||||
#include <QtMath>
|
||||
|
||||
#include <QDebug>
|
||||
#include <cstddef>
|
||||
#include "VisualGroup.h"
|
||||
#include "ui/themes/ThemeManager.h"
|
||||
#include <QDebug>
|
||||
|
||||
#include <Application.h>
|
||||
#include <InstanceList.h>
|
||||
@ -68,8 +65,7 @@ bool listsIntersect(const QList<T>& l1, const QList<T> t2)
|
||||
return false;
|
||||
}
|
||||
|
||||
InstanceView::InstanceView(QWidget *parent)
|
||||
: QAbstractItemView(parent)
|
||||
InstanceView::InstanceView(QWidget* parent) : QAbstractItemView(parent)
|
||||
{
|
||||
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
|
||||
@ -84,23 +80,23 @@ InstanceView::~InstanceView()
|
||||
m_groups.clear();
|
||||
}
|
||||
|
||||
void InstanceView::setModel(QAbstractItemModel *model)
|
||||
void InstanceView::setModel(QAbstractItemModel* model)
|
||||
{
|
||||
QAbstractItemView::setModel(model);
|
||||
connect(model, &QAbstractItemModel::modelReset, this, &InstanceView::modelReset);
|
||||
connect(model, &QAbstractItemModel::rowsRemoved, this, &InstanceView::rowsRemoved);
|
||||
}
|
||||
|
||||
void InstanceView::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles)
|
||||
void InstanceView::dataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight, const QVector<int>& roles)
|
||||
{
|
||||
scheduleDelayedItemsLayout();
|
||||
}
|
||||
void InstanceView::rowsInserted(const QModelIndex &parent, int start, int end)
|
||||
void InstanceView::rowsInserted(const QModelIndex& parent, int start, int end)
|
||||
{
|
||||
scheduleDelayedItemsLayout();
|
||||
}
|
||||
|
||||
void InstanceView::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
|
||||
void InstanceView::rowsAboutToBeRemoved(const QModelIndex& parent, int start, int end)
|
||||
{
|
||||
scheduleDelayedItemsLayout();
|
||||
}
|
||||
@ -118,7 +114,8 @@ void InstanceView::rowsRemoved()
|
||||
void InstanceView::currentChanged(const QModelIndex& current, const QModelIndex& previous)
|
||||
{
|
||||
QAbstractItemView::currentChanged(current, previous);
|
||||
// TODO: for accessibility support, implement+register a factory, steal QAccessibleTable from Qt and return an instance of it for InstanceView.
|
||||
// TODO: for accessibility support, implement+register a factory, steal QAccessibleTable from Qt and return an instance of it for
|
||||
// InstanceView.
|
||||
#ifndef QT_NO_ACCESSIBILITY
|
||||
if (QAccessible::isActive() && current.isValid()) {
|
||||
QAccessibleEvent event(this, QAccessible::Focus);
|
||||
@ -128,19 +125,13 @@ void InstanceView::currentChanged(const QModelIndex& current, const QModelIndex&
|
||||
#endif /* !QT_NO_ACCESSIBILITY */
|
||||
}
|
||||
|
||||
|
||||
class LocaleString : public QString
|
||||
{
|
||||
public:
|
||||
LocaleString(const char *s) : QString(s)
|
||||
{
|
||||
}
|
||||
LocaleString(const QString &s) : QString(s)
|
||||
{
|
||||
}
|
||||
class LocaleString : public QString {
|
||||
public:
|
||||
LocaleString(const char* s) : QString(s) {}
|
||||
LocaleString(const QString& s) : QString(s) {}
|
||||
};
|
||||
|
||||
inline bool operator<(const LocaleString &lhs, const LocaleString &rhs)
|
||||
inline bool operator<(const LocaleString& lhs, const LocaleString& rhs)
|
||||
{
|
||||
return (QString::localeAwareCompare(lhs, rhs) < 0);
|
||||
}
|
||||
@ -148,33 +139,28 @@ inline bool operator<(const LocaleString &lhs, const LocaleString &rhs)
|
||||
void InstanceView::updateScrollbar()
|
||||
{
|
||||
int previousScroll = verticalScrollBar()->value();
|
||||
if (m_groups.isEmpty())
|
||||
{
|
||||
if (m_groups.isEmpty()) {
|
||||
verticalScrollBar()->setRange(0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
int totalHeight = 0;
|
||||
// top margin
|
||||
totalHeight += m_categoryMargin;
|
||||
int itemScroll = 0;
|
||||
for (auto category : m_groups)
|
||||
{
|
||||
for (auto category : m_groups) {
|
||||
category->m_verticalPosition = totalHeight;
|
||||
totalHeight += category->totalHeight() + m_categoryMargin;
|
||||
if(!itemScroll && category->totalHeight() != 0)
|
||||
{
|
||||
if (!itemScroll && category->totalHeight() != 0) {
|
||||
itemScroll = category->contentHeight() / category->numRows();
|
||||
}
|
||||
}
|
||||
// do not divide by zero
|
||||
if(itemScroll == 0)
|
||||
if (itemScroll == 0)
|
||||
itemScroll = 64;
|
||||
|
||||
totalHeight += m_bottomMargin;
|
||||
verticalScrollBar()->setSingleStep ( itemScroll );
|
||||
const int rowsPerPage = qMax ( viewport()->height() / itemScroll, 1 );
|
||||
verticalScrollBar()->setPageStep ( rowsPerPage * itemScroll );
|
||||
verticalScrollBar()->setSingleStep(itemScroll);
|
||||
const int rowsPerPage = qMax(viewport()->height() / itemScroll, 1);
|
||||
verticalScrollBar()->setPageStep(rowsPerPage * itemScroll);
|
||||
|
||||
verticalScrollBar()->setRange(0, totalHeight - height());
|
||||
}
|
||||
@ -186,24 +172,19 @@ void InstanceView::updateGeometries()
|
||||
{
|
||||
geometryCache.clear();
|
||||
|
||||
QMap<LocaleString, VisualGroup *> cats;
|
||||
QMap<LocaleString, VisualGroup*> cats;
|
||||
|
||||
for (int i = 0; i < model()->rowCount(); ++i)
|
||||
{
|
||||
for (int i = 0; i < model()->rowCount(); ++i) {
|
||||
const QString groupName = model()->index(i, 0).data(InstanceViewRoles::GroupRole).toString();
|
||||
if (!cats.contains(groupName))
|
||||
{
|
||||
VisualGroup *old = this->category(groupName);
|
||||
if (old)
|
||||
{
|
||||
if (!cats.contains(groupName)) {
|
||||
VisualGroup* old = this->category(groupName);
|
||||
if (old) {
|
||||
auto cat = new VisualGroup(old);
|
||||
cats.insert(groupName, cat);
|
||||
cat->update();
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
auto cat = new VisualGroup(groupName, this);
|
||||
if(fVisibility) {
|
||||
if (fVisibility) {
|
||||
cat->collapsed = fVisibility(groupName);
|
||||
}
|
||||
cats.insert(groupName, cat);
|
||||
@ -218,43 +199,36 @@ void InstanceView::updateGeometries()
|
||||
viewport()->update();
|
||||
}
|
||||
|
||||
bool InstanceView::isIndexHidden(const QModelIndex &index) const
|
||||
bool InstanceView::isIndexHidden(const QModelIndex& index) const
|
||||
{
|
||||
VisualGroup *cat = category(index);
|
||||
if (cat)
|
||||
{
|
||||
VisualGroup* cat = category(index);
|
||||
if (cat) {
|
||||
return cat->collapsed;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
VisualGroup *InstanceView::category(const QModelIndex &index) const
|
||||
VisualGroup* InstanceView::category(const QModelIndex& index) const
|
||||
{
|
||||
return category(index.data(InstanceViewRoles::GroupRole).toString());
|
||||
}
|
||||
|
||||
VisualGroup *InstanceView::category(const QString &cat) const
|
||||
VisualGroup* InstanceView::category(const QString& cat) const
|
||||
{
|
||||
for (auto group : m_groups)
|
||||
{
|
||||
if (group->text == cat)
|
||||
{
|
||||
for (auto group : m_groups) {
|
||||
if (group->text == cat) {
|
||||
return group;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
VisualGroup *InstanceView::categoryAt(const QPoint &pos, VisualGroup::HitResults & result) const
|
||||
VisualGroup* InstanceView::categoryAt(const QPoint& pos, VisualGroup::HitResults& result) const
|
||||
{
|
||||
for (auto group : m_groups)
|
||||
{
|
||||
for (auto group : m_groups) {
|
||||
result = group->hitScan(pos);
|
||||
if(result != VisualGroup::NoHit)
|
||||
{
|
||||
if (result != VisualGroup::NoHit) {
|
||||
return group;
|
||||
}
|
||||
}
|
||||
@ -262,14 +236,13 @@ VisualGroup *InstanceView::categoryAt(const QPoint &pos, VisualGroup::HitResults
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QString InstanceView::groupNameAt(const QPoint &point)
|
||||
QString InstanceView::groupNameAt(const QPoint& point)
|
||||
{
|
||||
executeDelayedItemsLayout();
|
||||
|
||||
VisualGroup::HitResults hitresult;
|
||||
auto group = categoryAt(point + offset(), hitresult);
|
||||
if(group && (hitresult & (VisualGroup::HeaderHit | VisualGroup::BodyHit)))
|
||||
{
|
||||
if (group && (hitresult & (VisualGroup::HeaderHit | VisualGroup::BodyHit))) {
|
||||
return group->text;
|
||||
}
|
||||
return QString();
|
||||
@ -290,7 +263,7 @@ int InstanceView::itemWidth() const
|
||||
return m_itemWidth;
|
||||
}
|
||||
|
||||
void InstanceView::mousePressEvent(QMouseEvent *event)
|
||||
void InstanceView::mousePressEvent(QMouseEvent* event)
|
||||
{
|
||||
executeDelayedItemsLayout();
|
||||
|
||||
@ -305,17 +278,14 @@ void InstanceView::mousePressEvent(QMouseEvent *event)
|
||||
|
||||
VisualGroup::HitResults hitresult;
|
||||
m_pressedCategory = categoryAt(geometryPos, hitresult);
|
||||
if (m_pressedCategory && hitresult & VisualGroup::CheckboxHit)
|
||||
{
|
||||
if (m_pressedCategory && hitresult & VisualGroup::CheckboxHit) {
|
||||
setState(m_pressedCategory->collapsed ? ExpandingState : CollapsingState);
|
||||
event->accept();
|
||||
return;
|
||||
}
|
||||
|
||||
if (index.isValid() && (index.flags() & Qt::ItemIsEnabled))
|
||||
{
|
||||
if(index != currentIndex())
|
||||
{
|
||||
if (index.isValid() && (index.flags() & Qt::ItemIsEnabled)) {
|
||||
if (index != currentIndex()) {
|
||||
// FIXME: better!
|
||||
m_currentCursorColumn = -1;
|
||||
}
|
||||
@ -331,15 +301,13 @@ void InstanceView::mousePressEvent(QMouseEvent *event)
|
||||
|
||||
// signal handlers may change the model
|
||||
emit pressed(index);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// Forces a finalize() even if mouse is pressed, but not on a item
|
||||
selectionModel()->select(QModelIndex(), QItemSelectionModel::Select);
|
||||
}
|
||||
}
|
||||
|
||||
void InstanceView::mouseMoveEvent(QMouseEvent *event)
|
||||
void InstanceView::mouseMoveEvent(QMouseEvent* event)
|
||||
{
|
||||
executeDelayedItemsLayout();
|
||||
|
||||
@ -347,16 +315,13 @@ void InstanceView::mouseMoveEvent(QMouseEvent *event)
|
||||
QPoint visualPos = event->pos();
|
||||
QPoint geometryPos = event->pos() + offset();
|
||||
|
||||
if (state() == ExpandingState || state() == CollapsingState)
|
||||
{
|
||||
if (state() == ExpandingState || state() == CollapsingState) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (state() == DraggingState)
|
||||
{
|
||||
if (state() == DraggingState) {
|
||||
topLeft = m_pressedPosition - offset();
|
||||
if ((topLeft - event->pos()).manhattanLength() > QApplication::startDragDistance())
|
||||
{
|
||||
if ((topLeft - event->pos()).manhattanLength() > QApplication::startDragDistance()) {
|
||||
m_pressedIndex = QModelIndex();
|
||||
startDrag(model()->supportedDragActions());
|
||||
setState(NoState);
|
||||
@ -365,39 +330,31 @@ void InstanceView::mouseMoveEvent(QMouseEvent *event)
|
||||
return;
|
||||
}
|
||||
|
||||
if (selectionMode() != SingleSelection)
|
||||
{
|
||||
if (selectionMode() != SingleSelection) {
|
||||
topLeft = m_pressedPosition - offset();
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
topLeft = geometryPos;
|
||||
}
|
||||
|
||||
if (m_pressedIndex.isValid() && (state() != DragSelectingState) &&
|
||||
(event->buttons() != Qt::NoButton) && !selectedIndexes().isEmpty())
|
||||
{
|
||||
if (m_pressedIndex.isValid() && (state() != DragSelectingState) && (event->buttons() != Qt::NoButton) && !selectedIndexes().isEmpty()) {
|
||||
setState(DraggingState);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((event->buttons() & Qt::LeftButton) && selectionModel())
|
||||
{
|
||||
if ((event->buttons() & Qt::LeftButton) && selectionModel()) {
|
||||
setState(DragSelectingState);
|
||||
|
||||
setSelection(QRect(visualPos, visualPos), QItemSelectionModel::ClearAndSelect);
|
||||
QModelIndex index = indexAt(visualPos);
|
||||
|
||||
// set at the end because it might scroll the view
|
||||
if (index.isValid() && (index != selectionModel()->currentIndex()) &&
|
||||
(index.flags() & Qt::ItemIsEnabled))
|
||||
{
|
||||
if (index.isValid() && (index != selectionModel()->currentIndex()) && (index.flags() & Qt::ItemIsEnabled)) {
|
||||
selectionModel()->setCurrentIndex(index, QItemSelectionModel::NoUpdate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void InstanceView::mouseReleaseEvent(QMouseEvent *event)
|
||||
void InstanceView::mouseReleaseEvent(QMouseEvent* event)
|
||||
{
|
||||
executeDelayedItemsLayout();
|
||||
|
||||
@ -407,13 +364,11 @@ void InstanceView::mouseReleaseEvent(QMouseEvent *event)
|
||||
|
||||
VisualGroup::HitResults hitresult;
|
||||
|
||||
bool click = (index == m_pressedIndex && index.isValid()) ||
|
||||
(m_pressedCategory && m_pressedCategory == categoryAt(geometryPos, hitresult));
|
||||
bool click =
|
||||
(index == m_pressedIndex && index.isValid()) || (m_pressedCategory && m_pressedCategory == categoryAt(geometryPos, hitresult));
|
||||
|
||||
if (click && m_pressedCategory)
|
||||
{
|
||||
if (state() == ExpandingState)
|
||||
{
|
||||
if (click && m_pressedCategory) {
|
||||
if (state() == ExpandingState) {
|
||||
m_pressedCategory->collapsed = false;
|
||||
emit groupStateChanged(m_pressedCategory->text, false);
|
||||
|
||||
@ -423,9 +378,7 @@ void InstanceView::mouseReleaseEvent(QMouseEvent *event)
|
||||
m_pressedCategory = nullptr;
|
||||
setState(NoState);
|
||||
return;
|
||||
}
|
||||
else if (state() == CollapsingState)
|
||||
{
|
||||
} else if (state() == CollapsingState) {
|
||||
m_pressedCategory->collapsed = true;
|
||||
emit groupStateChanged(m_pressedCategory->text, true);
|
||||
|
||||
@ -442,10 +395,8 @@ void InstanceView::mouseReleaseEvent(QMouseEvent *event)
|
||||
|
||||
setState(NoState);
|
||||
|
||||
if (click)
|
||||
{
|
||||
if (event->button() == Qt::LeftButton)
|
||||
{
|
||||
if (click) {
|
||||
if (event->button() == Qt::LeftButton) {
|
||||
emit clicked(index);
|
||||
}
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
@ -454,34 +405,24 @@ void InstanceView::mouseReleaseEvent(QMouseEvent *event)
|
||||
#else
|
||||
QStyleOptionViewItem option = viewOptions();
|
||||
#endif
|
||||
if (m_pressedAlreadySelected)
|
||||
{
|
||||
if (m_pressedAlreadySelected) {
|
||||
option.state |= QStyle::State_Selected;
|
||||
}
|
||||
if ((model()->flags(index) & Qt::ItemIsEnabled) &&
|
||||
style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick, &option, this))
|
||||
{
|
||||
style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick, &option, this)) {
|
||||
emit activated(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void InstanceView::mouseDoubleClickEvent(QMouseEvent *event)
|
||||
void InstanceView::mouseDoubleClickEvent(QMouseEvent* event)
|
||||
{
|
||||
executeDelayedItemsLayout();
|
||||
|
||||
QModelIndex index = indexAt(event->pos());
|
||||
if (!index.isValid() || !(index.flags() & Qt::ItemIsEnabled) || (m_pressedIndex != index))
|
||||
{
|
||||
QMouseEvent me(
|
||||
QEvent::MouseButtonPress,
|
||||
event->localPos(),
|
||||
event->windowPos(),
|
||||
event->screenPos(),
|
||||
event->button(),
|
||||
event->buttons(),
|
||||
event->modifiers()
|
||||
);
|
||||
if (!index.isValid() || !(index.flags() & Qt::ItemIsEnabled) || (m_pressedIndex != index)) {
|
||||
QMouseEvent me(QEvent::MouseButtonPress, event->localPos(), event->windowPos(), event->screenPos(), event->button(),
|
||||
event->buttons(), event->modifiers());
|
||||
mousePressEvent(&me);
|
||||
return;
|
||||
}
|
||||
@ -495,8 +436,7 @@ void InstanceView::mouseDoubleClickEvent(QMouseEvent *event)
|
||||
#else
|
||||
QStyleOptionViewItem option = viewOptions();
|
||||
#endif
|
||||
if ((model()->flags(index) & Qt::ItemIsEnabled) && !style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick, &option, this))
|
||||
{
|
||||
if ((model()->flags(index) & Qt::ItemIsEnabled) && !style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick, &option, this)) {
|
||||
emit activated(index);
|
||||
}
|
||||
}
|
||||
@ -586,28 +526,21 @@ void InstanceView::paintEvent(QPaintEvent* event)
|
||||
option.rect = backup;
|
||||
}
|
||||
|
||||
for (int i = 0; i < model()->rowCount(); ++i)
|
||||
{
|
||||
for (int i = 0; i < model()->rowCount(); ++i) {
|
||||
const QModelIndex index = model()->index(i, 0);
|
||||
if (isIndexHidden(index))
|
||||
{
|
||||
if (isIndexHidden(index)) {
|
||||
continue;
|
||||
}
|
||||
Qt::ItemFlags flags = index.flags();
|
||||
option.rect = visualRect(index);
|
||||
option.features |= QStyleOptionViewItem::WrapText;
|
||||
if (flags & Qt::ItemIsSelectable && selectionModel()->isSelected(index))
|
||||
{
|
||||
option.state |= selectionModel()->isSelected(index) ? QStyle::State_Selected
|
||||
: QStyle::State_None;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (flags & Qt::ItemIsSelectable && selectionModel()->isSelected(index)) {
|
||||
option.state |= selectionModel()->isSelected(index) ? QStyle::State_Selected : QStyle::State_None;
|
||||
} else {
|
||||
option.state &= ~QStyle::State_Selected;
|
||||
}
|
||||
option.state |= (index == currentIndex()) ? QStyle::State_HasFocus : QStyle::State_None;
|
||||
if (!(flags & Qt::ItemIsEnabled))
|
||||
{
|
||||
if (!(flags & Qt::ItemIsEnabled)) {
|
||||
option.state &= ~QStyle::State_Enabled;
|
||||
}
|
||||
itemDelegate()->paint(&painter, option, index);
|
||||
@ -645,27 +578,23 @@ void InstanceView::paintEvent(QPaintEvent* event)
|
||||
#endif
|
||||
}
|
||||
|
||||
void InstanceView::resizeEvent(QResizeEvent *event)
|
||||
void InstanceView::resizeEvent(QResizeEvent* event)
|
||||
{
|
||||
int newItemsPerRow = calculateItemsPerRow();
|
||||
if(newItemsPerRow != m_currentItemsPerRow)
|
||||
{
|
||||
if (newItemsPerRow != m_currentItemsPerRow) {
|
||||
m_currentCursorColumn = -1;
|
||||
m_currentItemsPerRow = newItemsPerRow;
|
||||
updateGeometries();
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
updateScrollbar();
|
||||
}
|
||||
}
|
||||
|
||||
void InstanceView::dragEnterEvent(QDragEnterEvent *event)
|
||||
void InstanceView::dragEnterEvent(QDragEnterEvent* event)
|
||||
{
|
||||
executeDelayedItemsLayout();
|
||||
|
||||
if (!isDragEventAccepted(event))
|
||||
{
|
||||
if (!isDragEventAccepted(event)) {
|
||||
return;
|
||||
}
|
||||
m_lastDragPosition = event->pos() + offset();
|
||||
@ -673,12 +602,11 @@ void InstanceView::dragEnterEvent(QDragEnterEvent *event)
|
||||
event->accept();
|
||||
}
|
||||
|
||||
void InstanceView::dragMoveEvent(QDragMoveEvent *event)
|
||||
void InstanceView::dragMoveEvent(QDragMoveEvent* event)
|
||||
{
|
||||
executeDelayedItemsLayout();
|
||||
|
||||
if (!isDragEventAccepted(event))
|
||||
{
|
||||
if (!isDragEventAccepted(event)) {
|
||||
return;
|
||||
}
|
||||
m_lastDragPosition = event->pos() + offset();
|
||||
@ -686,7 +614,7 @@ void InstanceView::dragMoveEvent(QDragMoveEvent *event)
|
||||
event->accept();
|
||||
}
|
||||
|
||||
void InstanceView::dragLeaveEvent(QDragLeaveEvent *event)
|
||||
void InstanceView::dragLeaveEvent(QDragLeaveEvent* event)
|
||||
{
|
||||
executeDelayedItemsLayout();
|
||||
|
||||
@ -694,7 +622,7 @@ void InstanceView::dragLeaveEvent(QDragLeaveEvent *event)
|
||||
viewport()->update();
|
||||
}
|
||||
|
||||
void InstanceView::dropEvent(QDropEvent *event)
|
||||
void InstanceView::dropEvent(QDropEvent* event)
|
||||
{
|
||||
executeDelayedItemsLayout();
|
||||
|
||||
@ -705,16 +633,13 @@ void InstanceView::dropEvent(QDropEvent *event)
|
||||
|
||||
auto mimedata = event->mimeData();
|
||||
|
||||
if (event->source() == this)
|
||||
{
|
||||
if(event->possibleActions() & Qt::MoveAction)
|
||||
{
|
||||
std::pair<VisualGroup *, VisualGroup::HitResults> dropPos = rowDropPos(event->pos());
|
||||
const VisualGroup *group = dropPos.first;
|
||||
if (event->source() == this) {
|
||||
if (event->possibleActions() & Qt::MoveAction) {
|
||||
std::pair<VisualGroup*, VisualGroup::HitResults> dropPos = rowDropPos(event->pos());
|
||||
const VisualGroup* group = dropPos.first;
|
||||
auto hitresult = dropPos.second;
|
||||
|
||||
if (hitresult == VisualGroup::HitResult::NoHit)
|
||||
{
|
||||
if (hitresult == VisualGroup::HitResult::NoHit) {
|
||||
viewport()->update();
|
||||
return;
|
||||
}
|
||||
@ -731,14 +656,12 @@ void InstanceView::dropEvent(QDropEvent *event)
|
||||
}
|
||||
|
||||
// check if the action is supported
|
||||
if (!mimedata)
|
||||
{
|
||||
if (!mimedata) {
|
||||
return;
|
||||
}
|
||||
|
||||
// files dropped from outside?
|
||||
if (mimedata->hasUrls())
|
||||
{
|
||||
if (mimedata->hasUrls()) {
|
||||
auto urls = mimedata->urls();
|
||||
event->accept();
|
||||
emit droppedURLs(urls);
|
||||
@ -750,57 +673,52 @@ void InstanceView::startDrag(Qt::DropActions supportedActions)
|
||||
executeDelayedItemsLayout();
|
||||
|
||||
QModelIndexList indexes = selectionModel()->selectedIndexes();
|
||||
if(indexes.count() == 0)
|
||||
if (indexes.count() == 0)
|
||||
return;
|
||||
|
||||
QMimeData *data = model()->mimeData(indexes);
|
||||
if (!data)
|
||||
{
|
||||
QMimeData* data = model()->mimeData(indexes);
|
||||
if (!data) {
|
||||
return;
|
||||
}
|
||||
QRect rect;
|
||||
QPixmap pixmap = renderToPixmap(indexes, &rect);
|
||||
QDrag *drag = new QDrag(this);
|
||||
QDrag* drag = new QDrag(this);
|
||||
drag->setPixmap(pixmap);
|
||||
drag->setMimeData(data);
|
||||
drag->setHotSpot(m_pressedPosition - rect.topLeft());
|
||||
Qt::DropAction defaultDropAction = Qt::IgnoreAction;
|
||||
if (this->defaultDropAction() != Qt::IgnoreAction && (supportedActions & this->defaultDropAction()))
|
||||
{
|
||||
if (this->defaultDropAction() != Qt::IgnoreAction && (supportedActions & this->defaultDropAction())) {
|
||||
defaultDropAction = this->defaultDropAction();
|
||||
}
|
||||
/*auto action = */
|
||||
drag->exec(supportedActions, defaultDropAction);
|
||||
}
|
||||
|
||||
QRect InstanceView::visualRect(const QModelIndex &index) const
|
||||
QRect InstanceView::visualRect(const QModelIndex& index) const
|
||||
{
|
||||
const_cast<InstanceView*>(this)->executeDelayedItemsLayout();
|
||||
|
||||
return geometryRect(index).translated(-offset());
|
||||
}
|
||||
|
||||
QRect InstanceView::geometryRect(const QModelIndex &index) const
|
||||
QRect InstanceView::geometryRect(const QModelIndex& index) const
|
||||
{
|
||||
const_cast<InstanceView*>(this)->executeDelayedItemsLayout();
|
||||
|
||||
if (!index.isValid() || isIndexHidden(index) || index.column() > 0)
|
||||
{
|
||||
if (!index.isValid() || isIndexHidden(index) || index.column() > 0) {
|
||||
return QRect();
|
||||
}
|
||||
|
||||
int row = index.row();
|
||||
if(geometryCache.contains(row))
|
||||
{
|
||||
if (geometryCache.contains(row)) {
|
||||
return *geometryCache[row];
|
||||
}
|
||||
|
||||
const VisualGroup *cat = category(index);
|
||||
const VisualGroup* cat = category(index);
|
||||
QPair<int, int> pos = cat->positionOf(index);
|
||||
int x = pos.first;
|
||||
// int y = pos.second;
|
||||
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
QStyleOptionViewItem option;
|
||||
initViewItemOption(&option);
|
||||
@ -816,43 +734,38 @@ QRect InstanceView::geometryRect(const QModelIndex &index) const
|
||||
return out;
|
||||
}
|
||||
|
||||
QModelIndex InstanceView::indexAt(const QPoint &point) const
|
||||
QModelIndex InstanceView::indexAt(const QPoint& point) const
|
||||
{
|
||||
const_cast<InstanceView*>(this)->executeDelayedItemsLayout();
|
||||
|
||||
for (int i = 0; i < model()->rowCount(); ++i)
|
||||
{
|
||||
for (int i = 0; i < model()->rowCount(); ++i) {
|
||||
QModelIndex index = model()->index(i, 0);
|
||||
if (visualRect(index).contains(point))
|
||||
{
|
||||
if (visualRect(index).contains(point)) {
|
||||
return index;
|
||||
}
|
||||
}
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
void InstanceView::setSelection(const QRect &rect, const QItemSelectionModel::SelectionFlags commands)
|
||||
void InstanceView::setSelection(const QRect& rect, const QItemSelectionModel::SelectionFlags commands)
|
||||
{
|
||||
executeDelayedItemsLayout();
|
||||
|
||||
for (int i = 0; i < model()->rowCount(); ++i)
|
||||
{
|
||||
for (int i = 0; i < model()->rowCount(); ++i) {
|
||||
QModelIndex index = model()->index(i, 0);
|
||||
QRect itemRect = visualRect(index);
|
||||
if (itemRect.intersects(rect))
|
||||
{
|
||||
if (itemRect.intersects(rect)) {
|
||||
selectionModel()->select(index, commands);
|
||||
update(itemRect.translated(-offset()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QPixmap InstanceView::renderToPixmap(const QModelIndexList &indices, QRect *r) const
|
||||
QPixmap InstanceView::renderToPixmap(const QModelIndexList& indices, QRect* r) const
|
||||
{
|
||||
Q_ASSERT(r);
|
||||
auto paintPairs = draggablePaintPairs(indices, r);
|
||||
if (paintPairs.isEmpty())
|
||||
{
|
||||
if (paintPairs.isEmpty()) {
|
||||
return QPixmap();
|
||||
}
|
||||
QPixmap pixmap(r->size());
|
||||
@ -865,23 +778,21 @@ QPixmap InstanceView::renderToPixmap(const QModelIndexList &indices, QRect *r) c
|
||||
QStyleOptionViewItem option = viewOptions();
|
||||
#endif
|
||||
option.state |= QStyle::State_Selected;
|
||||
for (int j = 0; j < paintPairs.count(); ++j)
|
||||
{
|
||||
for (int j = 0; j < paintPairs.count(); ++j) {
|
||||
option.rect = paintPairs.at(j).first.translated(-r->topLeft());
|
||||
const QModelIndex ¤t = paintPairs.at(j).second;
|
||||
const QModelIndex& current = paintPairs.at(j).second;
|
||||
itemDelegate()->paint(&painter, option, current);
|
||||
}
|
||||
return pixmap;
|
||||
}
|
||||
|
||||
QList<std::pair<QRect, QModelIndex>> InstanceView::draggablePaintPairs(const QModelIndexList &indices, QRect *r) const
|
||||
QList<std::pair<QRect, QModelIndex>> InstanceView::draggablePaintPairs(const QModelIndexList& indices, QRect* r) const
|
||||
{
|
||||
Q_ASSERT(r);
|
||||
QRect &rect = *r;
|
||||
QRect& rect = *r;
|
||||
QList<std::pair<QRect, QModelIndex>> ret;
|
||||
for (int i = 0; i < indices.count(); ++i)
|
||||
{
|
||||
const QModelIndex &index = indices.at(i);
|
||||
for (int i = 0; i < indices.count(); ++i) {
|
||||
const QModelIndex& index = indices.at(i);
|
||||
const QRect current = geometryRect(index);
|
||||
ret += std::make_pair(current, index);
|
||||
rect |= current;
|
||||
@ -889,12 +800,12 @@ QList<std::pair<QRect, QModelIndex>> InstanceView::draggablePaintPairs(const QMo
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool InstanceView::isDragEventAccepted(QDropEvent *event)
|
||||
bool InstanceView::isDragEventAccepted(QDropEvent* event)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
std::pair<VisualGroup *, VisualGroup::HitResults> InstanceView::rowDropPos(const QPoint &pos)
|
||||
std::pair<VisualGroup*, VisualGroup::HitResults> InstanceView::rowDropPos(const QPoint& pos)
|
||||
{
|
||||
VisualGroup::HitResults hitresult;
|
||||
auto group = categoryAt(pos + offset(), hitresult);
|
||||
@ -906,21 +817,18 @@ QPoint InstanceView::offset() const
|
||||
return QPoint(horizontalOffset(), verticalOffset());
|
||||
}
|
||||
|
||||
QRegion InstanceView::visualRegionForSelection(const QItemSelection &selection) const
|
||||
QRegion InstanceView::visualRegionForSelection(const QItemSelection& selection) const
|
||||
{
|
||||
QRegion region;
|
||||
for (auto &range : selection)
|
||||
{
|
||||
for (auto& range : selection) {
|
||||
int start_row = range.top();
|
||||
int end_row = range.bottom();
|
||||
for (int row = start_row; row <= end_row; ++row)
|
||||
{
|
||||
for (int row = start_row; row <= end_row; ++row) {
|
||||
int start_column = range.left();
|
||||
int end_column = range.right();
|
||||
for (int column = start_column; column <= end_column; ++column)
|
||||
{
|
||||
for (int column = start_column; column <= end_column; ++column) {
|
||||
QModelIndex index = model()->index(row, column, rootIndex());
|
||||
region += visualRect(index); // OK
|
||||
region += visualRect(index); // OK
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -930,122 +838,97 @@ QRegion InstanceView::visualRegionForSelection(const QItemSelection &selection)
|
||||
QModelIndex InstanceView::moveCursor(QAbstractItemView::CursorAction cursorAction, Qt::KeyboardModifiers modifiers)
|
||||
{
|
||||
auto current = currentIndex();
|
||||
if(!current.isValid())
|
||||
{
|
||||
if (!current.isValid()) {
|
||||
return current;
|
||||
}
|
||||
auto cat = category(current);
|
||||
int group_index = m_groups.indexOf(cat);
|
||||
if(group_index < 0)
|
||||
if (group_index < 0)
|
||||
return current;
|
||||
|
||||
QPair<int, int> pos = cat->positionOf(current);
|
||||
int column = pos.first;
|
||||
int row = pos.second;
|
||||
if(m_currentCursorColumn < 0)
|
||||
{
|
||||
if (m_currentCursorColumn < 0) {
|
||||
m_currentCursorColumn = column;
|
||||
}
|
||||
switch(cursorAction)
|
||||
{
|
||||
case MoveUp:
|
||||
{
|
||||
if(row == 0)
|
||||
{
|
||||
int prevgroupindex = group_index-1;
|
||||
while(prevgroupindex >= 0)
|
||||
{
|
||||
switch (cursorAction) {
|
||||
case MoveUp: {
|
||||
if (row == 0) {
|
||||
int prevgroupindex = group_index - 1;
|
||||
while (prevgroupindex >= 0) {
|
||||
auto prevgroup = m_groups[prevgroupindex];
|
||||
if(prevgroup->collapsed)
|
||||
{
|
||||
if (prevgroup->collapsed) {
|
||||
prevgroupindex--;
|
||||
continue;
|
||||
}
|
||||
int newRow = prevgroup->numRows() - 1;
|
||||
int newRowSize = prevgroup->rows[newRow].size();
|
||||
int newColumn = m_currentCursorColumn;
|
||||
if (m_currentCursorColumn >= newRowSize)
|
||||
{
|
||||
if (m_currentCursorColumn >= newRowSize) {
|
||||
newColumn = newRowSize - 1;
|
||||
}
|
||||
return prevgroup->rows[newRow][newColumn];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
int newRow = row - 1;
|
||||
int newRowSize = cat->rows[newRow].size();
|
||||
int newColumn = m_currentCursorColumn;
|
||||
if (m_currentCursorColumn >= newRowSize)
|
||||
{
|
||||
if (m_currentCursorColumn >= newRowSize) {
|
||||
newColumn = newRowSize - 1;
|
||||
}
|
||||
return cat->rows[newRow][newColumn];
|
||||
}
|
||||
return current;
|
||||
}
|
||||
case MoveDown:
|
||||
{
|
||||
if(row == cat->rows.size() - 1)
|
||||
{
|
||||
int nextgroupindex = group_index+1;
|
||||
while (nextgroupindex < m_groups.size())
|
||||
{
|
||||
case MoveDown: {
|
||||
if (row == cat->rows.size() - 1) {
|
||||
int nextgroupindex = group_index + 1;
|
||||
while (nextgroupindex < m_groups.size()) {
|
||||
auto nextgroup = m_groups[nextgroupindex];
|
||||
if(nextgroup->collapsed)
|
||||
{
|
||||
if (nextgroup->collapsed) {
|
||||
nextgroupindex++;
|
||||
continue;
|
||||
}
|
||||
int newRowSize = nextgroup->rows[0].size();
|
||||
int newColumn = m_currentCursorColumn;
|
||||
if (m_currentCursorColumn >= newRowSize)
|
||||
{
|
||||
if (m_currentCursorColumn >= newRowSize) {
|
||||
newColumn = newRowSize - 1;
|
||||
}
|
||||
return nextgroup->rows[0][newColumn];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
int newRow = row + 1;
|
||||
int newRowSize = cat->rows[newRow].size();
|
||||
int newColumn = m_currentCursorColumn;
|
||||
if (m_currentCursorColumn >= newRowSize)
|
||||
{
|
||||
if (m_currentCursorColumn >= newRowSize) {
|
||||
newColumn = newRowSize - 1;
|
||||
}
|
||||
return cat->rows[newRow][newColumn];
|
||||
}
|
||||
return current;
|
||||
}
|
||||
case MoveLeft:
|
||||
{
|
||||
if(column > 0)
|
||||
{
|
||||
case MoveLeft: {
|
||||
if (column > 0) {
|
||||
m_currentCursorColumn = column - 1;
|
||||
return cat->rows[row][column - 1];
|
||||
}
|
||||
// TODO: moving to previous line
|
||||
return current;
|
||||
}
|
||||
case MoveRight:
|
||||
{
|
||||
if(column < cat->rows[row].size() - 1)
|
||||
{
|
||||
case MoveRight: {
|
||||
if (column < cat->rows[row].size() - 1) {
|
||||
m_currentCursorColumn = column + 1;
|
||||
return cat->rows[row][column + 1];
|
||||
}
|
||||
// TODO: moving to next line
|
||||
return current;
|
||||
}
|
||||
case MoveHome:
|
||||
{
|
||||
case MoveHome: {
|
||||
m_currentCursorColumn = 0;
|
||||
return cat->rows[row][0];
|
||||
}
|
||||
case MoveEnd:
|
||||
{
|
||||
case MoveEnd: {
|
||||
auto last = cat->rows[row].size() - 1;
|
||||
m_currentCursorColumn = last;
|
||||
return cat->rows[row][last];
|
||||
@ -1072,14 +955,13 @@ void InstanceView::scrollContentsBy(int dx, int dy)
|
||||
viewport()->scroll(dx, dy);
|
||||
}
|
||||
|
||||
void InstanceView::scrollTo(const QModelIndex &index, ScrollHint hint)
|
||||
void InstanceView::scrollTo(const QModelIndex& index, ScrollHint hint)
|
||||
{
|
||||
if (!index.isValid())
|
||||
return;
|
||||
|
||||
const QRect rect = visualRect(index);
|
||||
if (hint == EnsureVisible && viewport()->rect().contains(rect))
|
||||
{
|
||||
if (hint == EnsureVisible && viewport()->rect().contains(rect)) {
|
||||
viewport()->update(rect);
|
||||
return;
|
||||
}
|
||||
@ -1087,7 +969,7 @@ void InstanceView::scrollTo(const QModelIndex &index, ScrollHint hint)
|
||||
verticalScrollBar()->setValue(verticalScrollToValue(index, rect, hint));
|
||||
}
|
||||
|
||||
int InstanceView::verticalScrollToValue(const QModelIndex &index, const QRect &rect, QListView::ScrollHint hint) const
|
||||
int InstanceView::verticalScrollToValue(const QModelIndex& index, const QRect& rect, QListView::ScrollHint hint) const
|
||||
{
|
||||
const QRect area = viewport()->rect();
|
||||
const bool above = (hint == QListView::EnsureVisible && rect.top() < area.top());
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
/*
|
||||
* PolyMC - Minecraft Launcher
|
||||
* Prism Launcher - Minecraft Launcher
|
||||
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
@ -35,95 +35,86 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QListView>
|
||||
#include <QLineEdit>
|
||||
#include <QScrollBar>
|
||||
#include <QCache>
|
||||
#include "VisualGroup.h"
|
||||
#include <QLineEdit>
|
||||
#include <QListView>
|
||||
#include <QScrollBar>
|
||||
#include <functional>
|
||||
#include "VisualGroup.h"
|
||||
|
||||
struct InstanceViewRoles
|
||||
{
|
||||
enum
|
||||
{
|
||||
GroupRole = Qt::UserRole,
|
||||
ProgressValueRole,
|
||||
ProgressMaximumRole
|
||||
};
|
||||
struct InstanceViewRoles {
|
||||
enum { GroupRole = Qt::UserRole, ProgressValueRole, ProgressMaximumRole };
|
||||
};
|
||||
|
||||
class InstanceView : public QAbstractItemView
|
||||
{
|
||||
class InstanceView : public QAbstractItemView {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
InstanceView(QWidget *parent = 0);
|
||||
public:
|
||||
InstanceView(QWidget* parent = 0);
|
||||
~InstanceView();
|
||||
|
||||
void setModel(QAbstractItemModel *model) override;
|
||||
void setModel(QAbstractItemModel* model) override;
|
||||
|
||||
using visibilityFunction = std::function<bool(const QString &)>;
|
||||
void setSourceOfGroupCollapseStatus(visibilityFunction f) {
|
||||
fVisibility = f;
|
||||
}
|
||||
using visibilityFunction = std::function<bool(const QString&)>;
|
||||
void setSourceOfGroupCollapseStatus(visibilityFunction f) { fVisibility = f; }
|
||||
|
||||
/// return geometry rectangle occupied by the specified model item
|
||||
QRect geometryRect(const QModelIndex &index) const;
|
||||
QRect geometryRect(const QModelIndex& index) const;
|
||||
/// return visual rectangle occupied by the specified model item
|
||||
virtual QRect visualRect(const QModelIndex &index) const override;
|
||||
virtual QRect visualRect(const QModelIndex& index) const override;
|
||||
/// get the model index at the specified visual point
|
||||
virtual QModelIndex indexAt(const QPoint &point) const override;
|
||||
QString groupNameAt(const QPoint &point);
|
||||
void setSelection(const QRect &rect, const QItemSelectionModel::SelectionFlags commands) override;
|
||||
virtual QModelIndex indexAt(const QPoint& point) const override;
|
||||
QString groupNameAt(const QPoint& point);
|
||||
void setSelection(const QRect& rect, const QItemSelectionModel::SelectionFlags commands) override;
|
||||
|
||||
virtual int horizontalOffset() const override;
|
||||
virtual int verticalOffset() const override;
|
||||
virtual void scrollContentsBy(int dx, int dy) override;
|
||||
virtual void scrollTo(const QModelIndex &index, ScrollHint hint = EnsureVisible) override;
|
||||
virtual void scrollTo(const QModelIndex& index, ScrollHint hint = EnsureVisible) override;
|
||||
|
||||
virtual QModelIndex moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers) override;
|
||||
|
||||
virtual QRegion visualRegionForSelection(const QItemSelection &selection) const override;
|
||||
virtual QRegion visualRegionForSelection(const QItemSelection& selection) const override;
|
||||
|
||||
int spacing() const { return m_spacing; };
|
||||
void setPaintCat(bool visible);
|
||||
|
||||
public slots:
|
||||
public slots:
|
||||
virtual void updateGeometries() override;
|
||||
|
||||
protected slots:
|
||||
virtual void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles) override;
|
||||
virtual void rowsInserted(const QModelIndex &parent, int start, int end) override;
|
||||
virtual void rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end) override;
|
||||
protected slots:
|
||||
virtual void dataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight, const QVector<int>& roles) override;
|
||||
virtual void rowsInserted(const QModelIndex& parent, int start, int end) override;
|
||||
virtual void rowsAboutToBeRemoved(const QModelIndex& parent, int start, int end) override;
|
||||
void modelReset();
|
||||
void rowsRemoved();
|
||||
void currentChanged(const QModelIndex ¤t, const QModelIndex &previous) override;
|
||||
void currentChanged(const QModelIndex& current, const QModelIndex& previous) override;
|
||||
|
||||
signals:
|
||||
signals:
|
||||
void droppedURLs(QList<QUrl> urls);
|
||||
void groupStateChanged(QString group, bool collapsed);
|
||||
|
||||
protected:
|
||||
bool isIndexHidden(const QModelIndex &index) const override;
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
void mouseMoveEvent(QMouseEvent *event) override;
|
||||
void mouseReleaseEvent(QMouseEvent *event) override;
|
||||
void mouseDoubleClickEvent(QMouseEvent *event) override;
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
void resizeEvent(QResizeEvent *event) override;
|
||||
protected:
|
||||
bool isIndexHidden(const QModelIndex& index) const override;
|
||||
void mousePressEvent(QMouseEvent* event) override;
|
||||
void mouseMoveEvent(QMouseEvent* event) override;
|
||||
void mouseReleaseEvent(QMouseEvent* event) override;
|
||||
void mouseDoubleClickEvent(QMouseEvent* event) override;
|
||||
void paintEvent(QPaintEvent* event) override;
|
||||
void resizeEvent(QResizeEvent* event) override;
|
||||
|
||||
void dragEnterEvent(QDragEnterEvent *event) override;
|
||||
void dragMoveEvent(QDragMoveEvent *event) override;
|
||||
void dragLeaveEvent(QDragLeaveEvent *event) override;
|
||||
void dropEvent(QDropEvent *event) override;
|
||||
void dragEnterEvent(QDragEnterEvent* event) override;
|
||||
void dragMoveEvent(QDragMoveEvent* event) override;
|
||||
void dragLeaveEvent(QDragLeaveEvent* event) override;
|
||||
void dropEvent(QDropEvent* event) override;
|
||||
|
||||
void startDrag(Qt::DropActions supportedActions) override;
|
||||
|
||||
void updateScrollbar();
|
||||
|
||||
private:
|
||||
private:
|
||||
friend struct VisualGroup;
|
||||
QList<VisualGroup *> m_groups;
|
||||
QList<VisualGroup*> m_groups;
|
||||
|
||||
visibilityFunction fVisibility;
|
||||
|
||||
@ -135,7 +126,7 @@ private:
|
||||
int m_spacing = 5;
|
||||
int m_itemWidth = 100;
|
||||
int m_currentItemsPerRow = -1;
|
||||
int m_currentCursorColumn= -1;
|
||||
int m_currentCursorColumn = -1;
|
||||
mutable QCache<int, QRect> geometryCache;
|
||||
bool m_catVisible = false;
|
||||
QPixmap m_catPixmap;
|
||||
@ -144,30 +135,27 @@ private:
|
||||
QPoint m_pressedPosition;
|
||||
QPersistentModelIndex m_pressedIndex;
|
||||
bool m_pressedAlreadySelected;
|
||||
VisualGroup *m_pressedCategory;
|
||||
VisualGroup* m_pressedCategory;
|
||||
QItemSelectionModel::SelectionFlag m_ctrlDragSelectionFlag;
|
||||
QPoint m_lastDragPosition;
|
||||
|
||||
VisualGroup *category(const QModelIndex &index) const;
|
||||
VisualGroup *category(const QString &cat) const;
|
||||
VisualGroup *categoryAt(const QPoint &pos, VisualGroup::HitResults & result) const;
|
||||
VisualGroup* category(const QModelIndex& index) const;
|
||||
VisualGroup* category(const QString& cat) const;
|
||||
VisualGroup* categoryAt(const QPoint& pos, VisualGroup::HitResults& result) const;
|
||||
|
||||
int itemsPerRow() const
|
||||
{
|
||||
return m_currentItemsPerRow;
|
||||
};
|
||||
int itemsPerRow() const { return m_currentItemsPerRow; };
|
||||
int contentWidth() const;
|
||||
|
||||
private: /* methods */
|
||||
private: /* methods */
|
||||
int itemWidth() const;
|
||||
int calculateItemsPerRow() const;
|
||||
int verticalScrollToValue(const QModelIndex &index, const QRect &rect, QListView::ScrollHint hint) const;
|
||||
QPixmap renderToPixmap(const QModelIndexList &indices, QRect *r) const;
|
||||
QList<std::pair<QRect, QModelIndex>> draggablePaintPairs(const QModelIndexList &indices, QRect *r) const;
|
||||
int verticalScrollToValue(const QModelIndex& index, const QRect& rect, QListView::ScrollHint hint) const;
|
||||
QPixmap renderToPixmap(const QModelIndexList& indices, QRect* r) const;
|
||||
QList<std::pair<QRect, QModelIndex>> draggablePaintPairs(const QModelIndexList& indices, QRect* r) const;
|
||||
|
||||
bool isDragEventAccepted(QDropEvent *event);
|
||||
bool isDragEventAccepted(QDropEvent* event);
|
||||
|
||||
std::pair<VisualGroup *, VisualGroup::HitResults> rowDropPos(const QPoint &pos);
|
||||
std::pair<VisualGroup*, VisualGroup::HitResults> rowDropPos(const QPoint& pos);
|
||||
|
||||
QPoint offset() const;
|
||||
};
|
||||
|
@ -35,56 +35,48 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QString>
|
||||
#include <QRect>
|
||||
#include <QVector>
|
||||
#include <QString>
|
||||
#include <QStyleOption>
|
||||
#include <QVector>
|
||||
|
||||
class InstanceView;
|
||||
class QPainter;
|
||||
class QModelIndex;
|
||||
|
||||
struct VisualRow
|
||||
{
|
||||
struct VisualRow {
|
||||
QList<QModelIndex> items;
|
||||
int height = 0;
|
||||
int top = 0;
|
||||
inline int size() const
|
||||
{
|
||||
return items.size();
|
||||
}
|
||||
inline QModelIndex &operator[](int i)
|
||||
{
|
||||
return items[i];
|
||||
}
|
||||
inline int size() const { return items.size(); }
|
||||
inline QModelIndex& operator[](int i) { return items[i]; }
|
||||
};
|
||||
|
||||
struct VisualGroup
|
||||
{
|
||||
/* constructors */
|
||||
VisualGroup(QString text, InstanceView *view);
|
||||
explicit VisualGroup(const VisualGroup *other);
|
||||
struct VisualGroup {
|
||||
/* constructors */
|
||||
VisualGroup(QString text, InstanceView* view);
|
||||
explicit VisualGroup(const VisualGroup* other);
|
||||
|
||||
/* data */
|
||||
InstanceView *view = nullptr;
|
||||
/* data */
|
||||
InstanceView* view = nullptr;
|
||||
QString text;
|
||||
bool collapsed = false;
|
||||
QVector<VisualRow> rows;
|
||||
int firstItemIndex = 0;
|
||||
int m_verticalPosition = 0;
|
||||
|
||||
/* logic */
|
||||
/* logic */
|
||||
/// update the internal list of items and flow them into the rows.
|
||||
void update();
|
||||
|
||||
/// draw the header at y-position.
|
||||
void drawHeader(QPainter *painter, const QStyleOptionViewItem &option) const;
|
||||
void drawHeader(QPainter* painter, const QStyleOptionViewItem& option) const;
|
||||
|
||||
/// height of the group, in total. includes a small bit of padding.
|
||||
int totalHeight() const;
|
||||
|
||||
/// height of the group header, in pixels
|
||||
static int headerHeight() ;
|
||||
static int headerHeight();
|
||||
|
||||
/// height of the group content, in pixels
|
||||
int contentHeight() const;
|
||||
@ -99,26 +91,19 @@ struct VisualGroup
|
||||
int verticalPosition() const;
|
||||
|
||||
/// relative geometry - top of the row of the given item
|
||||
int rowTopOf(const QModelIndex &index) const;
|
||||
int rowTopOf(const QModelIndex& index) const;
|
||||
|
||||
/// height of the row of the given item
|
||||
int rowHeightOf(const QModelIndex &index) const;
|
||||
int rowHeightOf(const QModelIndex& index) const;
|
||||
|
||||
/// x/y position of the given item inside the group (in items!)
|
||||
QPair<int, int> positionOf(const QModelIndex &index) const;
|
||||
QPair<int, int> positionOf(const QModelIndex& index) const;
|
||||
|
||||
enum HitResult
|
||||
{
|
||||
NoHit = 0x0,
|
||||
TextHit = 0x1,
|
||||
CheckboxHit = 0x2,
|
||||
HeaderHit = 0x4,
|
||||
BodyHit = 0x8
|
||||
};
|
||||
enum HitResult { NoHit = 0x0, TextHit = 0x1, CheckboxHit = 0x2, HeaderHit = 0x4, BodyHit = 0x8 };
|
||||
Q_DECLARE_FLAGS(HitResults, HitResult)
|
||||
|
||||
/// shoot! BANG! what did we hit?
|
||||
HitResults hitScan (const QPoint &pos) const;
|
||||
HitResults hitScan(const QPoint& pos) const;
|
||||
|
||||
QList<QModelIndex> items() const;
|
||||
};
|
||||
|
@ -16,9 +16,9 @@
|
||||
#include "PageDialog.h"
|
||||
|
||||
#include <QDialogButtonBox>
|
||||
#include <QKeyEvent>
|
||||
#include <QPushButton>
|
||||
#include <QVBoxLayout>
|
||||
#include <QKeyEvent>
|
||||
|
||||
#include "Application.h"
|
||||
#include "settings/SettingsObject.h"
|
||||
@ -26,19 +26,18 @@
|
||||
#include "ui/widgets/IconLabel.h"
|
||||
#include "ui/widgets/PageContainer.h"
|
||||
|
||||
PageDialog::PageDialog(BasePageProvider *pageProvider, QString defaultId, QWidget *parent)
|
||||
: QDialog(parent)
|
||||
PageDialog::PageDialog(BasePageProvider* pageProvider, QString defaultId, QWidget* parent) : QDialog(parent)
|
||||
{
|
||||
setWindowTitle(pageProvider->dialogTitle());
|
||||
m_container = new PageContainer(pageProvider, defaultId, this);
|
||||
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
||||
QVBoxLayout* mainLayout = new QVBoxLayout;
|
||||
mainLayout->addWidget(m_container);
|
||||
mainLayout->setSpacing(0);
|
||||
mainLayout->setContentsMargins(0, 0, 0, 0);
|
||||
setLayout(mainLayout);
|
||||
|
||||
QDialogButtonBox *buttons = new QDialogButtonBox(QDialogButtonBox::Help | QDialogButtonBox::Close);
|
||||
QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Help | QDialogButtonBox::Close);
|
||||
buttons->button(QDialogButtonBox::Close)->setDefault(true);
|
||||
buttons->setContentsMargins(6, 0, 6, 0);
|
||||
m_container->addButtons(buttons);
|
||||
@ -49,11 +48,10 @@ PageDialog::PageDialog(BasePageProvider *pageProvider, QString defaultId, QWidge
|
||||
restoreGeometry(QByteArray::fromBase64(APPLICATION->settings()->get("PagedGeometry").toByteArray()));
|
||||
}
|
||||
|
||||
void PageDialog::closeEvent(QCloseEvent *event)
|
||||
void PageDialog::closeEvent(QCloseEvent* event)
|
||||
{
|
||||
qDebug() << "Paged dialog close requested";
|
||||
if (m_container->prepareToClose())
|
||||
{
|
||||
if (m_container->prepareToClose()) {
|
||||
qDebug() << "Paged dialog close approved";
|
||||
APPLICATION->settings()->set("PagedGeometry", saveGeometry().toBase64());
|
||||
qDebug() << "Paged dialog geometry saved";
|
||||
|
@ -19,17 +19,15 @@
|
||||
#include "ui/pages/BasePageProvider.h"
|
||||
|
||||
class PageContainer;
|
||||
class PageDialog : public QDialog
|
||||
{
|
||||
class PageDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit PageDialog(BasePageProvider *pageProvider, QString defaultId = QString(), QWidget *parent = 0);
|
||||
public:
|
||||
explicit PageDialog(BasePageProvider* pageProvider, QString defaultId = QString(), QWidget* parent = 0);
|
||||
virtual ~PageDialog() {}
|
||||
|
||||
private
|
||||
slots:
|
||||
virtual void closeEvent(QCloseEvent *event);
|
||||
private slots:
|
||||
virtual void closeEvent(QCloseEvent* event);
|
||||
|
||||
private:
|
||||
PageContainer * m_container;
|
||||
private:
|
||||
PageContainer* m_container;
|
||||
};
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
/*
|
||||
* PolyMC - Minecraft Launcher
|
||||
* Prism Launcher - Minecraft Launcher
|
||||
* Copyright (c) 2022 Jamie Mansfield <jmansfield@cadixdev.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
|
@ -2,9 +2,8 @@
|
||||
|
||||
class BasePage;
|
||||
|
||||
class BasePageContainer
|
||||
{
|
||||
public:
|
||||
class BasePageContainer {
|
||||
public:
|
||||
virtual ~BasePageContainer(){};
|
||||
virtual bool selectPage(QString pageId) = 0;
|
||||
virtual BasePage* getPage(QString pageId) { return nullptr; };
|
||||
|
@ -15,54 +15,43 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ui/pages/BasePage.h"
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include "ui/pages/BasePage.h"
|
||||
|
||||
class BasePageProvider
|
||||
{
|
||||
public:
|
||||
virtual QList<BasePage *> getPages() = 0;
|
||||
class BasePageProvider {
|
||||
public:
|
||||
virtual QList<BasePage*> getPages() = 0;
|
||||
virtual QString dialogTitle() = 0;
|
||||
};
|
||||
|
||||
class GenericPageProvider : public BasePageProvider
|
||||
{
|
||||
typedef std::function<BasePage *()> PageCreator;
|
||||
public:
|
||||
explicit GenericPageProvider(const QString &dialogTitle)
|
||||
: m_dialogTitle(dialogTitle)
|
||||
{
|
||||
}
|
||||
class GenericPageProvider : public BasePageProvider {
|
||||
typedef std::function<BasePage*()> PageCreator;
|
||||
|
||||
public:
|
||||
explicit GenericPageProvider(const QString& dialogTitle) : m_dialogTitle(dialogTitle) {}
|
||||
virtual ~GenericPageProvider() {}
|
||||
|
||||
QList<BasePage *> getPages() override
|
||||
QList<BasePage*> getPages() override
|
||||
{
|
||||
QList<BasePage *> pages;
|
||||
for (PageCreator creator : m_creators)
|
||||
{
|
||||
QList<BasePage*> pages;
|
||||
for (PageCreator creator : m_creators) {
|
||||
pages.append(creator());
|
||||
}
|
||||
return pages;
|
||||
}
|
||||
QString dialogTitle() override { return m_dialogTitle; }
|
||||
|
||||
void setDialogTitle(const QString &title)
|
||||
{
|
||||
m_dialogTitle = title;
|
||||
}
|
||||
void addPageCreator(PageCreator page)
|
||||
{
|
||||
m_creators.append(page);
|
||||
}
|
||||
void setDialogTitle(const QString& title) { m_dialogTitle = title; }
|
||||
void addPageCreator(PageCreator page) { m_creators.append(page); }
|
||||
|
||||
template<typename PageClass>
|
||||
template <typename PageClass>
|
||||
void addPage()
|
||||
{
|
||||
addPageCreator([](){return new PageClass();});
|
||||
addPageCreator([]() { return new PageClass(); });
|
||||
}
|
||||
|
||||
private:
|
||||
private:
|
||||
QList<PageCreator> m_creators;
|
||||
QString m_dialogTitle;
|
||||
};
|
||||
|
@ -39,37 +39,30 @@
|
||||
#include "APIPage.h"
|
||||
#include "ui_APIPage.h"
|
||||
|
||||
#include <QMessageBox>
|
||||
#include <QFileDialog>
|
||||
#include <QMessageBox>
|
||||
#include <QRegularExpression>
|
||||
#include <QStandardPaths>
|
||||
#include <QTabBar>
|
||||
#include <QValidator>
|
||||
#include <QVariant>
|
||||
|
||||
#include "Application.h"
|
||||
#include "BuildConfig.h"
|
||||
#include "net/PasteUpload.h"
|
||||
#include "settings/SettingsObject.h"
|
||||
#include "tools/BaseProfiler.h"
|
||||
#include "Application.h"
|
||||
#include "net/PasteUpload.h"
|
||||
#include "BuildConfig.h"
|
||||
|
||||
APIPage::APIPage(QWidget *parent) :
|
||||
QWidget(parent),
|
||||
ui(new Ui::APIPage)
|
||||
APIPage::APIPage(QWidget* parent) : QWidget(parent), ui(new Ui::APIPage)
|
||||
{
|
||||
// This is here so you can reorder the entries in the combobox without messing stuff up
|
||||
int comboBoxEntries[] = {
|
||||
PasteUpload::PasteType::Mclogs,
|
||||
PasteUpload::PasteType::NullPointer,
|
||||
PasteUpload::PasteType::PasteGG,
|
||||
PasteUpload::PasteType::Hastebin
|
||||
};
|
||||
int comboBoxEntries[] = { PasteUpload::PasteType::Mclogs, PasteUpload::PasteType::NullPointer, PasteUpload::PasteType::PasteGG,
|
||||
PasteUpload::PasteType::Hastebin };
|
||||
|
||||
static QRegularExpression validUrlRegExp("https?://.+");
|
||||
static QRegularExpression validMSAClientID(QRegularExpression::anchoredPattern(
|
||||
"[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}"));
|
||||
static QRegularExpression validFlameKey(QRegularExpression::anchoredPattern(
|
||||
"\\$2[ayb]\\$.{56}"));
|
||||
static QRegularExpression validMSAClientID(
|
||||
QRegularExpression::anchoredPattern("[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}"));
|
||||
static QRegularExpression validFlameKey(QRegularExpression::anchoredPattern("\\$2[ayb]\\$.{56}"));
|
||||
|
||||
ui->setupUi(this);
|
||||
|
||||
@ -77,7 +70,7 @@ APIPage::APIPage(QWidget *parent) :
|
||||
ui->pasteTypeComboBox->addItem(PasteUpload::PasteTypes.at(pasteType).name, pasteType);
|
||||
}
|
||||
|
||||
void (QComboBox::*currentIndexChangedSignal)(int) (&QComboBox::currentIndexChanged);
|
||||
void (QComboBox::*currentIndexChangedSignal)(int)(&QComboBox::currentIndexChanged);
|
||||
connect(ui->pasteTypeComboBox, currentIndexChangedSignal, this, &APIPage::updateBaseURLPlaceholder);
|
||||
// This function needs to be called even when the ComboBox's index is still in its default state.
|
||||
updateBaseURLPlaceholder(ui->pasteTypeComboBox->currentIndex());
|
||||
@ -110,12 +103,9 @@ void APIPage::resetBaseURLNote()
|
||||
|
||||
void APIPage::updateBaseURLNote(int index)
|
||||
{
|
||||
if (baseURLPasteType == index)
|
||||
{
|
||||
if (baseURLPasteType == index) {
|
||||
ui->baseURLNote->hide();
|
||||
}
|
||||
else if (!ui->baseURLEntry->text().isEmpty())
|
||||
{
|
||||
} else if (!ui->baseURLEntry->text().isEmpty()) {
|
||||
ui->baseURLNote->show();
|
||||
}
|
||||
}
|
||||
@ -136,8 +126,7 @@ void APIPage::loadSettings()
|
||||
|
||||
ui->baseURLEntry->setText(pastebinURL);
|
||||
int pasteTypeIndex = ui->pasteTypeComboBox->findData(pasteType);
|
||||
if (pasteTypeIndex == -1)
|
||||
{
|
||||
if (pasteTypeIndex == -1) {
|
||||
pasteTypeIndex = ui->pasteTypeComboBox->findData(PasteUpload::PasteType::Mclogs);
|
||||
ui->baseURLEntry->clear();
|
||||
}
|
||||
@ -167,15 +156,13 @@ void APIPage::applySettings()
|
||||
s->set("MSAClientIDOverride", msaClientID);
|
||||
QUrl metaURL(ui->metaURL->text());
|
||||
// Add required trailing slash
|
||||
if (!metaURL.isEmpty() && !metaURL.path().endsWith('/'))
|
||||
{
|
||||
if (!metaURL.isEmpty() && !metaURL.path().endsWith('/')) {
|
||||
QString path = metaURL.path();
|
||||
path.append('/');
|
||||
metaURL.setPath(path);
|
||||
}
|
||||
// Don't allow HTTP, since meta is basically RCE with all the jar files.
|
||||
if(!metaURL.isEmpty() && metaURL.scheme() == "http")
|
||||
{
|
||||
if (!metaURL.isEmpty() && metaURL.scheme() == "http") {
|
||||
metaURL.setScheme("https");
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
/*
|
||||
* PolyMC - Minecraft Launcher
|
||||
* Prism Launcher - Minecraft Launcher
|
||||
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
|
||||
* Copyright (c) 2022 Jamie Mansfield <jmansfield@cadixdev.org>
|
||||
* Copyright (c) 2022 Lenny McLennington <lenny@sneed.church>
|
||||
@ -39,41 +39,28 @@
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#include "ui/pages/BasePage.h"
|
||||
#include <Application.h>
|
||||
#include "ui/pages/BasePage.h"
|
||||
|
||||
namespace Ui {
|
||||
class APIPage;
|
||||
}
|
||||
|
||||
class APIPage : public QWidget, public BasePage
|
||||
{
|
||||
class APIPage : public QWidget, public BasePage {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit APIPage(QWidget *parent = 0);
|
||||
public:
|
||||
explicit APIPage(QWidget* parent = 0);
|
||||
~APIPage();
|
||||
|
||||
QString displayName() const override
|
||||
{
|
||||
return tr("APIs");
|
||||
}
|
||||
QIcon icon() const override
|
||||
{
|
||||
return APPLICATION->getThemedIcon("worlds");
|
||||
}
|
||||
QString id() const override
|
||||
{
|
||||
return "apis";
|
||||
}
|
||||
QString helpPage() const override
|
||||
{
|
||||
return "APIs";
|
||||
}
|
||||
QString displayName() const override { return tr("APIs"); }
|
||||
QIcon icon() const override { return APPLICATION->getThemedIcon("worlds"); }
|
||||
QString id() const override { return "apis"; }
|
||||
QString helpPage() const override { return "APIs"; }
|
||||
virtual bool apply() override;
|
||||
void retranslate() override;
|
||||
|
||||
private:
|
||||
private:
|
||||
int baseURLPasteType;
|
||||
void resetBaseURLNote();
|
||||
void updateBaseURLNote(int index);
|
||||
@ -81,7 +68,6 @@ private:
|
||||
void loadSettings();
|
||||
void applySettings();
|
||||
|
||||
private:
|
||||
Ui::APIPage *ui;
|
||||
private:
|
||||
Ui::APIPage* ui;
|
||||
};
|
||||
|
||||
|
@ -30,7 +30,7 @@
|
||||
</property>
|
||||
<widget class="QWidget" name="tab">
|
||||
<attribute name="title">
|
||||
<string notr="true">Services</string>
|
||||
<string>Services</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
/*
|
||||
* PolyMC - Minecraft Launcher
|
||||
* Prism Launcher - Minecraft Launcher
|
||||
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
|
||||
* Copyright (c) 2022 Jamie Mansfield <jmansfield@cadixdev.org>
|
||||
*
|
||||
@ -44,29 +44,27 @@
|
||||
|
||||
#include "net/NetJob.h"
|
||||
|
||||
#include "ui/dialogs/ProgressDialog.h"
|
||||
#include "ui/dialogs/OfflineLoginDialog.h"
|
||||
#include "ui/dialogs/CustomMessageBox.h"
|
||||
#include "ui/dialogs/LoginDialog.h"
|
||||
#include "ui/dialogs/MSALoginDialog.h"
|
||||
#include "ui/dialogs/CustomMessageBox.h"
|
||||
#include "ui/dialogs/OfflineLoginDialog.h"
|
||||
#include "ui/dialogs/ProgressDialog.h"
|
||||
#include "ui/dialogs/SkinUploadDialog.h"
|
||||
|
||||
#include "tasks/Task.h"
|
||||
#include "minecraft/auth/AccountTask.h"
|
||||
#include "minecraft/services/SkinDelete.h"
|
||||
#include "tasks/Task.h"
|
||||
|
||||
#include "Application.h"
|
||||
|
||||
#include "BuildConfig.h"
|
||||
|
||||
AccountListPage::AccountListPage(QWidget *parent)
|
||||
: QMainWindow(parent), ui(new Ui::AccountListPage)
|
||||
AccountListPage::AccountListPage(QWidget* parent) : QMainWindow(parent), ui(new Ui::AccountListPage)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->listView->setEmptyString(tr(
|
||||
"Welcome!\n"
|
||||
"If you're new here, you can click the \"Add\" button to add your Mojang or Minecraft account."
|
||||
));
|
||||
ui->listView->setEmptyString(
|
||||
tr("Welcome!\n"
|
||||
"If you're new here, you can click the \"Add\" button to add your Mojang or Minecraft account."));
|
||||
ui->listView->setEmptyMode(VersionListView::String);
|
||||
ui->listView->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
|
||||
@ -82,11 +80,10 @@ AccountListPage::AccountListPage(QWidget *parent)
|
||||
|
||||
// Expand the account column
|
||||
|
||||
QItemSelectionModel *selectionModel = ui->listView->selectionModel();
|
||||
QItemSelectionModel* selectionModel = ui->listView->selectionModel();
|
||||
|
||||
connect(selectionModel, &QItemSelectionModel::selectionChanged, [this](const QItemSelection &sel, const QItemSelection &dsel) {
|
||||
updateButtonStates();
|
||||
});
|
||||
connect(selectionModel, &QItemSelectionModel::selectionChanged,
|
||||
[this](const QItemSelection& sel, const QItemSelection& dsel) { updateButtonStates(); });
|
||||
connect(ui->listView, &VersionListView::customContextMenuRequested, this, &AccountListPage::ShowContextMenu);
|
||||
|
||||
connect(m_accounts.get(), &AccountList::listChanged, this, &AccountListPage::listChanged);
|
||||
@ -121,21 +118,19 @@ void AccountListPage::ShowContextMenu(const QPoint& pos)
|
||||
|
||||
void AccountListPage::changeEvent(QEvent* event)
|
||||
{
|
||||
if (event->type() == QEvent::LanguageChange)
|
||||
{
|
||||
if (event->type() == QEvent::LanguageChange) {
|
||||
ui->retranslateUi(this);
|
||||
}
|
||||
QMainWindow::changeEvent(event);
|
||||
}
|
||||
|
||||
QMenu * AccountListPage::createPopupMenu()
|
||||
QMenu* AccountListPage::createPopupMenu()
|
||||
{
|
||||
QMenu* filteredMenu = QMainWindow::createPopupMenu();
|
||||
filteredMenu->removeAction(ui->toolBar->toggleViewAction() );
|
||||
filteredMenu->removeAction(ui->toolBar->toggleViewAction());
|
||||
return filteredMenu;
|
||||
}
|
||||
|
||||
|
||||
void AccountListPage::listChanged()
|
||||
{
|
||||
updateButtonStates();
|
||||
@ -143,13 +138,10 @@ void AccountListPage::listChanged()
|
||||
|
||||
void AccountListPage::on_actionAddMojang_triggered()
|
||||
{
|
||||
MinecraftAccountPtr account = LoginDialog::newAccount(
|
||||
this,
|
||||
tr("Please enter your Mojang account email and password to add your account.")
|
||||
);
|
||||
MinecraftAccountPtr account =
|
||||
LoginDialog::newAccount(this, tr("Please enter your Mojang account email and password to add your account."));
|
||||
|
||||
if (account)
|
||||
{
|
||||
if (account) {
|
||||
m_accounts->addAccount(account);
|
||||
if (m_accounts->count() == 1) {
|
||||
m_accounts->setDefaultAccount(account);
|
||||
@ -159,13 +151,10 @@ void AccountListPage::on_actionAddMojang_triggered()
|
||||
|
||||
void AccountListPage::on_actionAddMicrosoft_triggered()
|
||||
{
|
||||
MinecraftAccountPtr account = MSALoginDialog::newAccount(
|
||||
this,
|
||||
tr("Please enter your Mojang account email and password to add your account.")
|
||||
);
|
||||
MinecraftAccountPtr account =
|
||||
MSALoginDialog::newAccount(this, tr("Please enter your Mojang account email and password to add your account."));
|
||||
|
||||
if (account)
|
||||
{
|
||||
if (account) {
|
||||
m_accounts->addAccount(account);
|
||||
if (m_accounts->count() == 1) {
|
||||
m_accounts->setDefaultAccount(account);
|
||||
@ -176,25 +165,17 @@ void AccountListPage::on_actionAddMicrosoft_triggered()
|
||||
void AccountListPage::on_actionAddOffline_triggered()
|
||||
{
|
||||
if (!m_accounts->anyAccountIsValid()) {
|
||||
QMessageBox::warning(
|
||||
this,
|
||||
tr("Error"),
|
||||
tr(
|
||||
"You must add a Microsoft or Mojang account that owns Minecraft before you can add an offline account."
|
||||
"<br><br>"
|
||||
"If you have lost your account you can contact Microsoft for support."
|
||||
)
|
||||
);
|
||||
QMessageBox::warning(this, tr("Error"),
|
||||
tr("You must add a Microsoft or Mojang account that owns Minecraft before you can add an offline account."
|
||||
"<br><br>"
|
||||
"If you have lost your account you can contact Microsoft for support."));
|
||||
return;
|
||||
}
|
||||
|
||||
MinecraftAccountPtr account = OfflineLoginDialog::newAccount(
|
||||
this,
|
||||
tr("Please enter your desired username to add your offline account.")
|
||||
);
|
||||
MinecraftAccountPtr account =
|
||||
OfflineLoginDialog::newAccount(this, tr("Please enter your desired username to add your offline account."));
|
||||
|
||||
if (account)
|
||||
{
|
||||
if (account) {
|
||||
m_accounts->addAccount(account);
|
||||
if (m_accounts->count() == 1) {
|
||||
m_accounts->setDefaultAccount(account);
|
||||
@ -205,14 +186,14 @@ void AccountListPage::on_actionAddOffline_triggered()
|
||||
void AccountListPage::on_actionRemove_triggered()
|
||||
{
|
||||
QModelIndexList selection = ui->listView->selectionModel()->selectedIndexes();
|
||||
if (selection.size() > 0)
|
||||
{
|
||||
if (selection.size() > 0) {
|
||||
QModelIndex selected = selection.first();
|
||||
m_accounts->removeAccount(selected);
|
||||
}
|
||||
}
|
||||
|
||||
void AccountListPage::on_actionRefresh_triggered() {
|
||||
void AccountListPage::on_actionRefresh_triggered()
|
||||
{
|
||||
QModelIndexList selection = ui->listView->selectionModel()->selectedIndexes();
|
||||
if (selection.size() > 0) {
|
||||
QModelIndex selected = selection.first();
|
||||
@ -221,12 +202,10 @@ void AccountListPage::on_actionRefresh_triggered() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void AccountListPage::on_actionSetDefault_triggered()
|
||||
{
|
||||
QModelIndexList selection = ui->listView->selectionModel()->selectedIndexes();
|
||||
if (selection.size() > 0)
|
||||
{
|
||||
if (selection.size() > 0) {
|
||||
QModelIndex selected = selection.first();
|
||||
MinecraftAccountPtr account = selected.data(AccountList::PointerRole).value<MinecraftAccountPtr>();
|
||||
m_accounts->setDefaultAccount(account);
|
||||
@ -245,8 +224,7 @@ void AccountListPage::updateButtonStates()
|
||||
bool hasSelection = !selection.empty();
|
||||
bool accountIsReady = false;
|
||||
bool accountIsOnline = false;
|
||||
if (hasSelection)
|
||||
{
|
||||
if (hasSelection) {
|
||||
QModelIndex selected = selection.first();
|
||||
MinecraftAccountPtr account = selected.data(AccountList::PointerRole).value<MinecraftAccountPtr>();
|
||||
accountIsReady = !account->isActive();
|
||||
@ -258,11 +236,10 @@ void AccountListPage::updateButtonStates()
|
||||
ui->actionDeleteSkin->setEnabled(accountIsReady && accountIsOnline);
|
||||
ui->actionRefresh->setEnabled(accountIsReady && accountIsOnline);
|
||||
|
||||
if(m_accounts->defaultAccount().get() == nullptr) {
|
||||
if (m_accounts->defaultAccount().get() == nullptr) {
|
||||
ui->actionNoDefault->setEnabled(false);
|
||||
ui->actionNoDefault->setChecked(true);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
ui->actionNoDefault->setEnabled(true);
|
||||
ui->actionNoDefault->setChecked(false);
|
||||
}
|
||||
@ -271,8 +248,7 @@ void AccountListPage::updateButtonStates()
|
||||
void AccountListPage::on_actionUploadSkin_triggered()
|
||||
{
|
||||
QModelIndexList selection = ui->listView->selectionModel()->selectedIndexes();
|
||||
if (selection.size() > 0)
|
||||
{
|
||||
if (selection.size() > 0) {
|
||||
QModelIndex selected = selection.first();
|
||||
MinecraftAccountPtr account = selected.data(AccountList::PointerRole).value<MinecraftAccountPtr>();
|
||||
SkinUploadDialog dialog(account, this);
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
/*
|
||||
* PolyMC - Minecraft Launcher
|
||||
* Prism Launcher - Minecraft Launcher
|
||||
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
|
||||
* Copyright (c) 2022 Jamie Mansfield <jmansfield@cadixdev.org>
|
||||
*
|
||||
@ -41,47 +41,35 @@
|
||||
|
||||
#include "ui/pages/BasePage.h"
|
||||
|
||||
#include "minecraft/auth/AccountList.h"
|
||||
#include "Application.h"
|
||||
#include "minecraft/auth/AccountList.h"
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
namespace Ui {
|
||||
class AccountListPage;
|
||||
}
|
||||
|
||||
class AuthenticateTask;
|
||||
|
||||
class AccountListPage : public QMainWindow, public BasePage
|
||||
{
|
||||
class AccountListPage : public QMainWindow, public BasePage {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit AccountListPage(QWidget *parent = 0);
|
||||
public:
|
||||
explicit AccountListPage(QWidget* parent = 0);
|
||||
~AccountListPage();
|
||||
|
||||
QString displayName() const override
|
||||
{
|
||||
return tr("Accounts");
|
||||
}
|
||||
QString displayName() const override { return tr("Accounts"); }
|
||||
QIcon icon() const override
|
||||
{
|
||||
auto icon = APPLICATION->getThemedIcon("accounts");
|
||||
if(icon.isNull())
|
||||
{
|
||||
if (icon.isNull()) {
|
||||
icon = APPLICATION->getThemedIcon("noaccount");
|
||||
}
|
||||
return icon;
|
||||
}
|
||||
QString id() const override
|
||||
{
|
||||
return "accounts";
|
||||
}
|
||||
QString helpPage() const override
|
||||
{
|
||||
return "Getting-Started#adding-an-account";
|
||||
}
|
||||
QString id() const override { return "accounts"; }
|
||||
QString helpPage() const override { return "Getting-Started#adding-an-account"; }
|
||||
void retranslate() override;
|
||||
|
||||
public slots:
|
||||
public slots:
|
||||
void on_actionAddMojang_triggered();
|
||||
void on_actionAddMicrosoft_triggered();
|
||||
void on_actionAddOffline_triggered();
|
||||
@ -97,12 +85,12 @@ public slots:
|
||||
//! Updates the states of the dialog's buttons.
|
||||
void updateButtonStates();
|
||||
|
||||
protected slots:
|
||||
void ShowContextMenu(const QPoint &pos);
|
||||
protected slots:
|
||||
void ShowContextMenu(const QPoint& pos);
|
||||
|
||||
private:
|
||||
void changeEvent(QEvent * event) override;
|
||||
QMenu * createPopupMenu() override;
|
||||
private:
|
||||
void changeEvent(QEvent* event) override;
|
||||
QMenu* createPopupMenu() override;
|
||||
shared_qobject_ptr<AccountList> m_accounts;
|
||||
Ui::AccountListPage *ui;
|
||||
Ui::AccountListPage* ui;
|
||||
};
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
/*
|
||||
* PolyMC - Minecraft Launcher
|
||||
* Prism Launcher - Minecraft Launcher
|
||||
* Copyright (c) 2022 Jamie Mansfield <jmansfield@cadixdev.org>
|
||||
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
|
||||
*
|
||||
@ -35,13 +35,12 @@
|
||||
*/
|
||||
|
||||
#include "CustomCommandsPage.h"
|
||||
#include <QVBoxLayout>
|
||||
#include <QTabWidget>
|
||||
#include <QTabBar>
|
||||
#include <QTabWidget>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
CustomCommandsPage::CustomCommandsPage(QWidget* parent): QWidget(parent)
|
||||
CustomCommandsPage::CustomCommandsPage(QWidget* parent) : QWidget(parent)
|
||||
{
|
||||
|
||||
auto verticalLayout = new QVBoxLayout(this);
|
||||
verticalLayout->setObjectName(QStringLiteral("verticalLayout"));
|
||||
verticalLayout->setContentsMargins(0, 0, 0, 0);
|
||||
@ -56,9 +55,7 @@ CustomCommandsPage::CustomCommandsPage(QWidget* parent): QWidget(parent)
|
||||
loadSettings();
|
||||
}
|
||||
|
||||
CustomCommandsPage::~CustomCommandsPage()
|
||||
{
|
||||
}
|
||||
CustomCommandsPage::~CustomCommandsPage() {}
|
||||
|
||||
bool CustomCommandsPage::apply()
|
||||
{
|
||||
@ -77,13 +74,8 @@ void CustomCommandsPage::applySettings()
|
||||
void CustomCommandsPage::loadSettings()
|
||||
{
|
||||
auto s = APPLICATION->settings();
|
||||
commands->initialize(
|
||||
false,
|
||||
true,
|
||||
s->get("PreLaunchCommand").toString(),
|
||||
s->get("WrapperCommand").toString(),
|
||||
s->get("PostExitCommand").toString()
|
||||
);
|
||||
commands->initialize(false, true, s->get("PreLaunchCommand").toString(), s->get("WrapperCommand").toString(),
|
||||
s->get("PostExitCommand").toString());
|
||||
}
|
||||
|
||||
void CustomCommandsPage::retranslate()
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
/*
|
||||
* PolyMC - Minecraft Launcher
|
||||
* Prism Launcher - Minecraft Launcher
|
||||
* Copyright (c) 2022 Jamie Mansfield <jmansfield@cadixdev.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
@ -35,42 +35,29 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <QDialog>
|
||||
#include <memory>
|
||||
|
||||
#include "ui/pages/BasePage.h"
|
||||
#include <Application.h>
|
||||
#include "ui/pages/BasePage.h"
|
||||
#include "ui/widgets/CustomCommands.h"
|
||||
|
||||
class CustomCommandsPage : public QWidget, public BasePage
|
||||
{
|
||||
class CustomCommandsPage : public QWidget, public BasePage {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit CustomCommandsPage(QWidget *parent = 0);
|
||||
public:
|
||||
explicit CustomCommandsPage(QWidget* parent = 0);
|
||||
~CustomCommandsPage();
|
||||
|
||||
QString displayName() const override
|
||||
{
|
||||
return tr("Custom Commands");
|
||||
}
|
||||
QIcon icon() const override
|
||||
{
|
||||
return APPLICATION->getThemedIcon("custom-commands");
|
||||
}
|
||||
QString id() const override
|
||||
{
|
||||
return "custom-commands";
|
||||
}
|
||||
QString helpPage() const override
|
||||
{
|
||||
return "Custom-commands";
|
||||
}
|
||||
QString displayName() const override { return tr("Custom Commands"); }
|
||||
QIcon icon() const override { return APPLICATION->getThemedIcon("custom-commands"); }
|
||||
QString id() const override { return "custom-commands"; }
|
||||
QString helpPage() const override { return "Custom-commands"; }
|
||||
bool apply() override;
|
||||
void retranslate() override;
|
||||
|
||||
private:
|
||||
private:
|
||||
void applySettings();
|
||||
void loadSettings();
|
||||
CustomCommands * commands;
|
||||
CustomCommands* commands;
|
||||
};
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
/*
|
||||
* PolyMC - Minecraft Launcher
|
||||
* Prism Launcher - Minecraft Launcher
|
||||
* Copyright (c) 2022 Jamie Mansfield <jmansfield@cadixdev.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
@ -36,20 +36,18 @@
|
||||
#include "ExternalToolsPage.h"
|
||||
#include "ui_ExternalToolsPage.h"
|
||||
|
||||
#include <QMessageBox>
|
||||
#include <QFileDialog>
|
||||
#include <QMessageBox>
|
||||
#include <QStandardPaths>
|
||||
#include <QTabBar>
|
||||
|
||||
#include <FileSystem.h>
|
||||
#include <tools/MCEditTool.h>
|
||||
#include "Application.h"
|
||||
#include "settings/SettingsObject.h"
|
||||
#include "tools/BaseProfiler.h"
|
||||
#include <FileSystem.h>
|
||||
#include "Application.h"
|
||||
#include <tools/MCEditTool.h>
|
||||
|
||||
ExternalToolsPage::ExternalToolsPage(QWidget *parent) :
|
||||
QWidget(parent),
|
||||
ui(new Ui::ExternalToolsPage)
|
||||
ExternalToolsPage::ExternalToolsPage(QWidget* parent) : QWidget(parent), ui(new Ui::ExternalToolsPage)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->tabWidget->tabBar()->hide();
|
||||
@ -87,12 +85,9 @@ void ExternalToolsPage::applySettings()
|
||||
|
||||
// Editors
|
||||
QString jsonEditor = ui->jsonEditorTextBox->text();
|
||||
if (!jsonEditor.isEmpty() &&
|
||||
(!QFileInfo(jsonEditor).exists() || !QFileInfo(jsonEditor).isExecutable()))
|
||||
{
|
||||
if (!jsonEditor.isEmpty() && (!QFileInfo(jsonEditor).exists() || !QFileInfo(jsonEditor).isExecutable())) {
|
||||
QString found = QStandardPaths::findExecutable(jsonEditor);
|
||||
if (!found.isEmpty())
|
||||
{
|
||||
if (!found.isEmpty()) {
|
||||
jsonEditor = found;
|
||||
}
|
||||
}
|
||||
@ -103,21 +98,16 @@ void ExternalToolsPage::on_jprofilerPathBtn_clicked()
|
||||
{
|
||||
QString raw_dir = ui->jprofilerPathEdit->text();
|
||||
QString error;
|
||||
do
|
||||
{
|
||||
do {
|
||||
raw_dir = QFileDialog::getExistingDirectory(this, tr("JProfiler Folder"), raw_dir);
|
||||
if (raw_dir.isEmpty())
|
||||
{
|
||||
if (raw_dir.isEmpty()) {
|
||||
break;
|
||||
}
|
||||
QString cooked_dir = FS::NormalizePath(raw_dir);
|
||||
if (!APPLICATION->profilers()["jprofiler"]->check(cooked_dir, &error))
|
||||
{
|
||||
if (!APPLICATION->profilers()["jprofiler"]->check(cooked_dir, &error)) {
|
||||
QMessageBox::critical(this, tr("Error"), tr("Error while checking JProfiler install:\n%1").arg(error));
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ui->jprofilerPathEdit->setText(cooked_dir);
|
||||
break;
|
||||
}
|
||||
@ -126,12 +116,9 @@ void ExternalToolsPage::on_jprofilerPathBtn_clicked()
|
||||
void ExternalToolsPage::on_jprofilerCheckBtn_clicked()
|
||||
{
|
||||
QString error;
|
||||
if (!APPLICATION->profilers()["jprofiler"]->check(ui->jprofilerPathEdit->text(), &error))
|
||||
{
|
||||
if (!APPLICATION->profilers()["jprofiler"]->check(ui->jprofilerPathEdit->text(), &error)) {
|
||||
QMessageBox::critical(this, tr("Error"), tr("Error while checking JProfiler install:\n%1").arg(error));
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
QMessageBox::information(this, tr("OK"), tr("JProfiler setup seems to be OK"));
|
||||
}
|
||||
}
|
||||
@ -140,21 +127,16 @@ void ExternalToolsPage::on_jvisualvmPathBtn_clicked()
|
||||
{
|
||||
QString raw_dir = ui->jvisualvmPathEdit->text();
|
||||
QString error;
|
||||
do
|
||||
{
|
||||
do {
|
||||
raw_dir = QFileDialog::getOpenFileName(this, tr("JVisualVM Executable"), raw_dir);
|
||||
if (raw_dir.isEmpty())
|
||||
{
|
||||
if (raw_dir.isEmpty()) {
|
||||
break;
|
||||
}
|
||||
QString cooked_dir = FS::NormalizePath(raw_dir);
|
||||
if (!APPLICATION->profilers()["jvisualvm"]->check(cooked_dir, &error))
|
||||
{
|
||||
if (!APPLICATION->profilers()["jvisualvm"]->check(cooked_dir, &error)) {
|
||||
QMessageBox::critical(this, tr("Error"), tr("Error while checking JVisualVM install:\n%1").arg(error));
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ui->jvisualvmPathEdit->setText(cooked_dir);
|
||||
break;
|
||||
}
|
||||
@ -163,12 +145,9 @@ void ExternalToolsPage::on_jvisualvmPathBtn_clicked()
|
||||
void ExternalToolsPage::on_jvisualvmCheckBtn_clicked()
|
||||
{
|
||||
QString error;
|
||||
if (!APPLICATION->profilers()["jvisualvm"]->check(ui->jvisualvmPathEdit->text(), &error))
|
||||
{
|
||||
if (!APPLICATION->profilers()["jvisualvm"]->check(ui->jvisualvmPathEdit->text(), &error)) {
|
||||
QMessageBox::critical(this, tr("Error"), tr("Error while checking JVisualVM install:\n%1").arg(error));
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
QMessageBox::information(this, tr("OK"), tr("JVisualVM setup seems to be OK"));
|
||||
}
|
||||
}
|
||||
@ -177,25 +156,20 @@ void ExternalToolsPage::on_mceditPathBtn_clicked()
|
||||
{
|
||||
QString raw_dir = ui->mceditPathEdit->text();
|
||||
QString error;
|
||||
do
|
||||
{
|
||||
do {
|
||||
#ifdef Q_OS_OSX
|
||||
raw_dir = QFileDialog::getOpenFileName(this, tr("MCEdit Application"), raw_dir);
|
||||
#else
|
||||
raw_dir = QFileDialog::getExistingDirectory(this, tr("MCEdit Folder"), raw_dir);
|
||||
#endif
|
||||
if (raw_dir.isEmpty())
|
||||
{
|
||||
if (raw_dir.isEmpty()) {
|
||||
break;
|
||||
}
|
||||
QString cooked_dir = FS::NormalizePath(raw_dir);
|
||||
if (!APPLICATION->mcedit()->check(cooked_dir, error))
|
||||
{
|
||||
if (!APPLICATION->mcedit()->check(cooked_dir, error)) {
|
||||
QMessageBox::critical(this, tr("Error"), tr("Error while checking MCEdit install:\n%1").arg(error));
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ui->mceditPathEdit->setText(cooked_dir);
|
||||
break;
|
||||
}
|
||||
@ -204,43 +178,34 @@ void ExternalToolsPage::on_mceditPathBtn_clicked()
|
||||
void ExternalToolsPage::on_mceditCheckBtn_clicked()
|
||||
{
|
||||
QString error;
|
||||
if (!APPLICATION->mcedit()->check(ui->mceditPathEdit->text(), error))
|
||||
{
|
||||
if (!APPLICATION->mcedit()->check(ui->mceditPathEdit->text(), error)) {
|
||||
QMessageBox::critical(this, tr("Error"), tr("Error while checking MCEdit install:\n%1").arg(error));
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
QMessageBox::information(this, tr("OK"), tr("MCEdit setup seems to be OK"));
|
||||
}
|
||||
}
|
||||
|
||||
void ExternalToolsPage::on_jsonEditorBrowseBtn_clicked()
|
||||
{
|
||||
QString raw_file = QFileDialog::getOpenFileName(
|
||||
this, tr("JSON Editor"),
|
||||
ui->jsonEditorTextBox->text().isEmpty()
|
||||
QString raw_file = QFileDialog::getOpenFileName(this, tr("JSON Editor"),
|
||||
ui->jsonEditorTextBox->text().isEmpty()
|
||||
#if defined(Q_OS_LINUX)
|
||||
? QString("/usr/bin")
|
||||
? QString("/usr/bin")
|
||||
#else
|
||||
? QStandardPaths::standardLocations(QStandardPaths::ApplicationsLocation).first()
|
||||
? QStandardPaths::standardLocations(QStandardPaths::ApplicationsLocation).first()
|
||||
#endif
|
||||
: ui->jsonEditorTextBox->text());
|
||||
: ui->jsonEditorTextBox->text());
|
||||
|
||||
if (raw_file.isEmpty())
|
||||
{
|
||||
if (raw_file.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
QString cooked_file = FS::NormalizePath(raw_file);
|
||||
|
||||
// it has to exist and be an executable
|
||||
if (QFileInfo(cooked_file).exists() && QFileInfo(cooked_file).isExecutable())
|
||||
{
|
||||
if (QFileInfo(cooked_file).exists() && QFileInfo(cooked_file).isExecutable()) {
|
||||
ui->jsonEditorTextBox->setText(cooked_file);
|
||||
}
|
||||
else
|
||||
{
|
||||
QMessageBox::warning(this, tr("Invalid"),
|
||||
tr("The file chosen does not seem to be an executable"));
|
||||
} else {
|
||||
QMessageBox::warning(this, tr("Invalid"), tr("The file chosen does not seem to be an executable"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
/*
|
||||
* PolyMC - Minecraft Launcher
|
||||
* Prism Launcher - Minecraft Launcher
|
||||
* Copyright (c) 2022 Jamie Mansfield <jmansfield@cadixdev.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
@ -37,54 +37,42 @@
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#include "ui/pages/BasePage.h"
|
||||
#include <Application.h>
|
||||
#include "ui/pages/BasePage.h"
|
||||
|
||||
namespace Ui {
|
||||
class ExternalToolsPage;
|
||||
}
|
||||
|
||||
class ExternalToolsPage : public QWidget, public BasePage
|
||||
{
|
||||
class ExternalToolsPage : public QWidget, public BasePage {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ExternalToolsPage(QWidget *parent = 0);
|
||||
public:
|
||||
explicit ExternalToolsPage(QWidget* parent = 0);
|
||||
~ExternalToolsPage();
|
||||
|
||||
QString displayName() const override
|
||||
{
|
||||
return tr("External Tools");
|
||||
}
|
||||
QString displayName() const override { return tr("External Tools"); }
|
||||
QIcon icon() const override
|
||||
{
|
||||
auto icon = APPLICATION->getThemedIcon("externaltools");
|
||||
if(icon.isNull())
|
||||
{
|
||||
if (icon.isNull()) {
|
||||
icon = APPLICATION->getThemedIcon("loadermods");
|
||||
}
|
||||
return icon;
|
||||
}
|
||||
QString id() const override
|
||||
{
|
||||
return "external-tools";
|
||||
}
|
||||
QString helpPage() const override
|
||||
{
|
||||
return "Tools";
|
||||
}
|
||||
QString id() const override { return "external-tools"; }
|
||||
QString helpPage() const override { return "Tools"; }
|
||||
virtual bool apply() override;
|
||||
void retranslate() override;
|
||||
|
||||
private:
|
||||
private:
|
||||
void loadSettings();
|
||||
void applySettings();
|
||||
|
||||
private:
|
||||
Ui::ExternalToolsPage *ui;
|
||||
private:
|
||||
Ui::ExternalToolsPage* ui;
|
||||
|
||||
private
|
||||
slots:
|
||||
private slots:
|
||||
void on_jprofilerPathBtn_clicked();
|
||||
void on_jprofilerCheckBtn_clicked();
|
||||
void on_jvisualvmPathBtn_clicked();
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
/*
|
||||
* PolyMC - Minecraft Launcher
|
||||
* Prism Launcher - Minecraft Launcher
|
||||
* Copyright (c) 2022 Jamie Mansfield <jmansfield@cadixdev.org>
|
||||
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
|
||||
*
|
||||
@ -38,22 +38,22 @@
|
||||
#include "JavaCommon.h"
|
||||
#include "ui_JavaPage.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QFileDialog>
|
||||
#include <QMessageBox>
|
||||
#include <QDir>
|
||||
#include <QTabBar>
|
||||
|
||||
#include "ui/dialogs/VersionSelectDialog.h"
|
||||
|
||||
#include "java/JavaUtils.h"
|
||||
#include "java/JavaInstallList.h"
|
||||
#include "java/JavaUtils.h"
|
||||
|
||||
#include "settings/SettingsObject.h"
|
||||
#include <FileSystem.h>
|
||||
#include "Application.h"
|
||||
#include <sys.h>
|
||||
#include "Application.h"
|
||||
#include "settings/SettingsObject.h"
|
||||
|
||||
JavaPage::JavaPage(QWidget *parent) : QWidget(parent), ui(new Ui::JavaPage)
|
||||
JavaPage::JavaPage(QWidget* parent) : QWidget(parent), ui(new Ui::JavaPage)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->tabWidget->tabBar()->hide();
|
||||
@ -80,13 +80,10 @@ void JavaPage::applySettings()
|
||||
// Memory
|
||||
int min = ui->minMemSpinBox->value();
|
||||
int max = ui->maxMemSpinBox->value();
|
||||
if(min < max)
|
||||
{
|
||||
if (min < max) {
|
||||
s->set("MinMemAlloc", min);
|
||||
s->set("MaxMemAlloc", max);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
s->set("MinMemAlloc", max);
|
||||
s->set("MaxMemAlloc", min);
|
||||
}
|
||||
@ -105,13 +102,10 @@ void JavaPage::loadSettings()
|
||||
// Memory
|
||||
int min = s->get("MinMemAlloc").toInt();
|
||||
int max = s->get("MaxMemAlloc").toInt();
|
||||
if(min < max)
|
||||
{
|
||||
if (min < max) {
|
||||
ui->minMemSpinBox->setValue(min);
|
||||
ui->maxMemSpinBox->setValue(max);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ui->minMemSpinBox->setValue(max);
|
||||
ui->maxMemSpinBox->setValue(min);
|
||||
}
|
||||
@ -137,8 +131,7 @@ void JavaPage::on_javaDetectBtn_clicked()
|
||||
vselect.setResizeOn(2);
|
||||
vselect.exec();
|
||||
|
||||
if (vselect.result() == QDialog::Accepted && vselect.selectedVersion())
|
||||
{
|
||||
if (vselect.result() == QDialog::Accepted && vselect.selectedVersion()) {
|
||||
java = std::dynamic_pointer_cast<JavaInstall>(vselect.selectedVersion());
|
||||
ui->javaPathTextBox->setText(java->path);
|
||||
}
|
||||
@ -149,15 +142,14 @@ void JavaPage::on_javaBrowseBtn_clicked()
|
||||
QString raw_path = QFileDialog::getOpenFileName(this, tr("Find Java executable"));
|
||||
|
||||
// do not allow current dir - it's dirty. Do not allow dirs that don't exist
|
||||
if(raw_path.isEmpty())
|
||||
{
|
||||
if (raw_path.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString cooked_path = FS::NormalizePath(raw_path);
|
||||
QFileInfo javaInfo(cooked_path);;
|
||||
if(!javaInfo.exists() || !javaInfo.isExecutable())
|
||||
{
|
||||
QFileInfo javaInfo(cooked_path);
|
||||
;
|
||||
if (!javaInfo.exists() || !javaInfo.isExecutable()) {
|
||||
return;
|
||||
}
|
||||
ui->javaPathTextBox->setText(cooked_path);
|
||||
@ -165,13 +157,11 @@ void JavaPage::on_javaBrowseBtn_clicked()
|
||||
|
||||
void JavaPage::on_javaTestBtn_clicked()
|
||||
{
|
||||
if(checker)
|
||||
{
|
||||
if (checker) {
|
||||
return;
|
||||
}
|
||||
checker.reset(new JavaCommon::TestCheck(
|
||||
this, ui->javaPathTextBox->text(), ui->jvmArgsTextBox->toPlainText().replace("\n", " "),
|
||||
ui->minMemSpinBox->value(), ui->maxMemSpinBox->value(), ui->permGenSpinBox->value()));
|
||||
checker.reset(new JavaCommon::TestCheck(this, ui->javaPathTextBox->text(), ui->jvmArgsTextBox->toPlainText().replace("\n", " "),
|
||||
ui->minMemSpinBox->value(), ui->maxMemSpinBox->value(), ui->permGenSpinBox->value()));
|
||||
connect(checker.get(), SIGNAL(finished()), SLOT(checkerFinished()));
|
||||
checker->run();
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
/*
|
||||
* PolyMC - Minecraft Launcher
|
||||
* Prism Launcher - Minecraft Launcher
|
||||
* Copyright (c) 2022 Jamie Mansfield <jmansfield@cadixdev.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
@ -35,62 +35,47 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <QDialog>
|
||||
#include "ui/pages/BasePage.h"
|
||||
#include "JavaCommon.h"
|
||||
#include <Application.h>
|
||||
#include <QObjectPtr.h>
|
||||
#include <QDialog>
|
||||
#include <memory>
|
||||
#include "JavaCommon.h"
|
||||
#include "ui/pages/BasePage.h"
|
||||
|
||||
class SettingsObject;
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
namespace Ui {
|
||||
class JavaPage;
|
||||
}
|
||||
|
||||
class JavaPage : public QWidget, public BasePage
|
||||
{
|
||||
class JavaPage : public QWidget, public BasePage {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit JavaPage(QWidget *parent = 0);
|
||||
public:
|
||||
explicit JavaPage(QWidget* parent = 0);
|
||||
~JavaPage();
|
||||
|
||||
QString displayName() const override
|
||||
{
|
||||
return tr("Java");
|
||||
}
|
||||
QIcon icon() const override
|
||||
{
|
||||
return APPLICATION->getThemedIcon("java");
|
||||
}
|
||||
QString id() const override
|
||||
{
|
||||
return "java-settings";
|
||||
}
|
||||
QString helpPage() const override
|
||||
{
|
||||
return "Java-settings";
|
||||
}
|
||||
QString displayName() const override { return tr("Java"); }
|
||||
QIcon icon() const override { return APPLICATION->getThemedIcon("java"); }
|
||||
QString id() const override { return "java-settings"; }
|
||||
QString helpPage() const override { return "Java-settings"; }
|
||||
bool apply() override;
|
||||
void retranslate() override;
|
||||
|
||||
void updateThresholds();
|
||||
|
||||
private:
|
||||
private:
|
||||
void applySettings();
|
||||
void loadSettings();
|
||||
|
||||
private
|
||||
slots:
|
||||
private slots:
|
||||
void on_javaDetectBtn_clicked();
|
||||
void on_javaTestBtn_clicked();
|
||||
void on_javaBrowseBtn_clicked();
|
||||
void on_maxMemSpinBox_valueChanged(int i);
|
||||
void checkerFinished();
|
||||
|
||||
private:
|
||||
Ui::JavaPage *ui;
|
||||
private:
|
||||
Ui::JavaPage* ui;
|
||||
unique_qobject_ptr<JavaCommon::TestCheck> checker;
|
||||
};
|
||||
|
@ -58,7 +58,7 @@
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="labelPermGen">
|
||||
<property name="text">
|
||||
<string notr="true">&PermGen:</string>
|
||||
<string>&PermGen:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>permGenSpinBox</cstring>
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
/*
|
||||
* PolyMC - Minecraft Launcher
|
||||
* Prism Launcher - Minecraft Launcher
|
||||
* Copyright (c) 2022 Jamie Mansfield <jmansfield@cadixdev.org>
|
||||
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
|
||||
*
|
||||
@ -36,23 +36,20 @@
|
||||
|
||||
#include "LanguagePage.h"
|
||||
|
||||
#include "ui/widgets/LanguageSelectionWidget.h"
|
||||
#include <QVBoxLayout>
|
||||
#include "ui/widgets/LanguageSelectionWidget.h"
|
||||
|
||||
LanguagePage::LanguagePage(QWidget* parent) :
|
||||
QWidget(parent)
|
||||
LanguagePage::LanguagePage(QWidget* parent) : QWidget(parent)
|
||||
{
|
||||
setObjectName(QStringLiteral("languagePage"));
|
||||
auto layout = new QVBoxLayout(this);
|
||||
mainWidget = new LanguageSelectionWidget(this);
|
||||
layout->setContentsMargins(0,0,0,0);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
layout->addWidget(mainWidget);
|
||||
retranslate();
|
||||
}
|
||||
|
||||
LanguagePage::~LanguagePage()
|
||||
{
|
||||
}
|
||||
LanguagePage::~LanguagePage() {}
|
||||
|
||||
bool LanguagePage::apply()
|
||||
{
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
/*
|
||||
* PolyMC - Minecraft Launcher
|
||||
* Prism Launcher - Minecraft Launcher
|
||||
* Copyright (c) 2022 Jamie Mansfield <jmansfield@cadixdev.org>
|
||||
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
|
||||
*
|
||||
@ -36,45 +36,32 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include "ui/pages/BasePage.h"
|
||||
#include <Application.h>
|
||||
#include <QWidget>
|
||||
#include <memory>
|
||||
#include "ui/pages/BasePage.h"
|
||||
|
||||
class LanguageSelectionWidget;
|
||||
|
||||
class LanguagePage : public QWidget, public BasePage
|
||||
{
|
||||
class LanguagePage : public QWidget, public BasePage {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit LanguagePage(QWidget *parent = 0);
|
||||
public:
|
||||
explicit LanguagePage(QWidget* parent = 0);
|
||||
virtual ~LanguagePage();
|
||||
|
||||
QString displayName() const override
|
||||
{
|
||||
return tr("Language");
|
||||
}
|
||||
QIcon icon() const override
|
||||
{
|
||||
return APPLICATION->getThemedIcon("language");
|
||||
}
|
||||
QString id() const override
|
||||
{
|
||||
return "language-settings";
|
||||
}
|
||||
QString helpPage() const override
|
||||
{
|
||||
return "Language-settings";
|
||||
}
|
||||
QString displayName() const override { return tr("Language"); }
|
||||
QIcon icon() const override { return APPLICATION->getThemedIcon("language"); }
|
||||
QString id() const override { return "language-settings"; }
|
||||
QString helpPage() const override { return "Language-settings"; }
|
||||
bool apply() override;
|
||||
|
||||
void retranslate() override;
|
||||
|
||||
private:
|
||||
private:
|
||||
void applySettings();
|
||||
void loadSettings();
|
||||
|
||||
private:
|
||||
LanguageSelectionWidget *mainWidget;
|
||||
private:
|
||||
LanguageSelectionWidget* mainWidget;
|
||||
};
|
||||
|
@ -38,17 +38,17 @@
|
||||
#include "LauncherPage.h"
|
||||
#include "ui_LauncherPage.h"
|
||||
|
||||
#include <QFileDialog>
|
||||
#include <QMessageBox>
|
||||
#include <QDir>
|
||||
#include <QTextCharFormat>
|
||||
#include <QFileDialog>
|
||||
#include <QMenuBar>
|
||||
#include <QMessageBox>
|
||||
#include <QTextCharFormat>
|
||||
|
||||
#include "settings/SettingsObject.h"
|
||||
#include <FileSystem.h>
|
||||
#include "Application.h"
|
||||
#include "BuildConfig.h"
|
||||
#include "DesktopServices.h"
|
||||
#include "settings/SettingsObject.h"
|
||||
#include "ui/themes/ITheme.h"
|
||||
#include "updater/ExternalUpdater.h"
|
||||
|
||||
@ -56,15 +56,14 @@
|
||||
#include <QProcess>
|
||||
|
||||
// FIXME: possibly move elsewhere
|
||||
enum InstSortMode
|
||||
{
|
||||
enum InstSortMode {
|
||||
// Sort alphabetically by name.
|
||||
Sort_Name,
|
||||
// Sort by which instance was launched most recently.
|
||||
Sort_LastLaunch
|
||||
};
|
||||
|
||||
LauncherPage::LauncherPage(QWidget *parent) : QWidget(parent), ui(new Ui::LauncherPage)
|
||||
LauncherPage::LauncherPage(QWidget* parent) : QWidget(parent), ui(new Ui::LauncherPage)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
auto origForeground = ui->fontPreview->palette().color(ui->fontPreview->foregroundRole());
|
||||
@ -104,46 +103,39 @@ void LauncherPage::on_instDirBrowseBtn_clicked()
|
||||
QString raw_dir = QFileDialog::getExistingDirectory(this, tr("Instance Folder"), ui->instDirTextBox->text());
|
||||
|
||||
// do not allow current dir - it's dirty. Do not allow dirs that don't exist
|
||||
if (!raw_dir.isEmpty() && QDir(raw_dir).exists())
|
||||
{
|
||||
if (!raw_dir.isEmpty() && QDir(raw_dir).exists()) {
|
||||
QString cooked_dir = FS::NormalizePath(raw_dir);
|
||||
if (FS::checkProblemticPathJava(QDir(cooked_dir)))
|
||||
{
|
||||
if (FS::checkProblemticPathJava(QDir(cooked_dir))) {
|
||||
QMessageBox warning;
|
||||
warning.setText(tr("You're trying to specify an instance folder which\'s path "
|
||||
"contains at least one \'!\'. "
|
||||
"Java is known to cause problems if that is the case, your "
|
||||
"instances (probably) won't start!"));
|
||||
warning.setText(
|
||||
tr("You're trying to specify an instance folder which\'s path "
|
||||
"contains at least one \'!\'. "
|
||||
"Java is known to cause problems if that is the case, your "
|
||||
"instances (probably) won't start!"));
|
||||
warning.setInformativeText(
|
||||
tr("Do you really want to use this path? "
|
||||
"Selecting \"No\" will close this and not alter your instance path."));
|
||||
warning.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
|
||||
int result = warning.exec();
|
||||
if (result == QMessageBox::Ok)
|
||||
{
|
||||
if (result == QMessageBox::Ok) {
|
||||
ui->instDirTextBox->setText(cooked_dir);
|
||||
}
|
||||
}
|
||||
else if(DesktopServices::isFlatpak() && raw_dir.startsWith("/run/user"))
|
||||
{
|
||||
} else if (DesktopServices::isFlatpak() && raw_dir.startsWith("/run/user")) {
|
||||
QMessageBox warning;
|
||||
warning.setText(tr("You're trying to specify an instance folder "
|
||||
"which was granted temporarily via Flatpak.\n"
|
||||
"This is known to cause problems. "
|
||||
"After a restart the launcher might break, "
|
||||
"because it will no longer have access to that directory.\n\n"
|
||||
"Granting %1 access to it via Flatseal is recommended.").arg(BuildConfig.LAUNCHER_DISPLAYNAME));
|
||||
warning.setInformativeText(
|
||||
tr("Do you want to proceed anyway?"));
|
||||
"which was granted temporarily via Flatpak.\n"
|
||||
"This is known to cause problems. "
|
||||
"After a restart the launcher might break, "
|
||||
"because it will no longer have access to that directory.\n\n"
|
||||
"Granting %1 access to it via Flatseal is recommended.")
|
||||
.arg(BuildConfig.LAUNCHER_DISPLAYNAME));
|
||||
warning.setInformativeText(tr("Do you want to proceed anyway?"));
|
||||
warning.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
|
||||
int result = warning.exec();
|
||||
if (result == QMessageBox::Ok)
|
||||
{
|
||||
if (result == QMessageBox::Ok) {
|
||||
ui->instDirTextBox->setText(cooked_dir);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ui->instDirTextBox->setText(cooked_dir);
|
||||
}
|
||||
}
|
||||
@ -154,8 +146,7 @@ void LauncherPage::on_iconsDirBrowseBtn_clicked()
|
||||
QString raw_dir = QFileDialog::getExistingDirectory(this, tr("Icons Folder"), ui->iconsDirTextBox->text());
|
||||
|
||||
// do not allow current dir - it's dirty. Do not allow dirs that don't exist
|
||||
if (!raw_dir.isEmpty() && QDir(raw_dir).exists())
|
||||
{
|
||||
if (!raw_dir.isEmpty() && QDir(raw_dir).exists()) {
|
||||
QString cooked_dir = FS::NormalizePath(raw_dir);
|
||||
ui->iconsDirTextBox->setText(cooked_dir);
|
||||
}
|
||||
@ -166,8 +157,7 @@ void LauncherPage::on_modsDirBrowseBtn_clicked()
|
||||
QString raw_dir = QFileDialog::getExistingDirectory(this, tr("Mods Folder"), ui->modsDirTextBox->text());
|
||||
|
||||
// do not allow current dir - it's dirty. Do not allow dirs that don't exist
|
||||
if (!raw_dir.isEmpty() && QDir(raw_dir).exists())
|
||||
{
|
||||
if (!raw_dir.isEmpty() && QDir(raw_dir).exists()) {
|
||||
QString cooked_dir = FS::NormalizePath(raw_dir);
|
||||
ui->modsDirTextBox->setText(cooked_dir);
|
||||
}
|
||||
@ -177,8 +167,7 @@ void LauncherPage::on_downloadsDirBrowseBtn_clicked()
|
||||
{
|
||||
QString raw_dir = QFileDialog::getExistingDirectory(this, tr("Downloads Folder"), ui->downloadsDirTextBox->text());
|
||||
|
||||
if (!raw_dir.isEmpty() && QDir(raw_dir).exists())
|
||||
{
|
||||
if (!raw_dir.isEmpty() && QDir(raw_dir).exists()) {
|
||||
QString cooked_dir = FS::NormalizePath(raw_dir);
|
||||
ui->downloadsDirTextBox->setText(cooked_dir);
|
||||
}
|
||||
@ -194,8 +183,7 @@ void LauncherPage::applySettings()
|
||||
auto s = APPLICATION->settings();
|
||||
|
||||
// Updates
|
||||
if (APPLICATION->updater())
|
||||
{
|
||||
if (APPLICATION->updater()) {
|
||||
APPLICATION->updater()->setAutomaticallyChecksForUpdates(ui->autoUpdateCheckBox->isChecked());
|
||||
}
|
||||
|
||||
@ -220,15 +208,14 @@ void LauncherPage::applySettings()
|
||||
s->set("DownloadsDirWatchRecursive", ui->downloadsDirWatchRecursiveCheckBox->isChecked());
|
||||
|
||||
auto sortMode = (InstSortMode)ui->sortingModeGroup->checkedId();
|
||||
switch (sortMode)
|
||||
{
|
||||
case Sort_LastLaunch:
|
||||
s->set("InstSortMode", "LastLaunch");
|
||||
break;
|
||||
case Sort_Name:
|
||||
default:
|
||||
s->set("InstSortMode", "Name");
|
||||
break;
|
||||
switch (sortMode) {
|
||||
case Sort_LastLaunch:
|
||||
s->set("InstSortMode", "LastLaunch");
|
||||
break;
|
||||
case Sort_Name:
|
||||
default:
|
||||
s->set("InstSortMode", "Name");
|
||||
break;
|
||||
}
|
||||
|
||||
// Mods
|
||||
@ -238,12 +225,10 @@ void LauncherPage::loadSettings()
|
||||
{
|
||||
auto s = APPLICATION->settings();
|
||||
// Updates
|
||||
if (APPLICATION->updater())
|
||||
{
|
||||
if (APPLICATION->updater()) {
|
||||
ui->autoUpdateCheckBox->setChecked(APPLICATION->updater()->getAutomaticallyChecksForUpdates());
|
||||
}
|
||||
|
||||
|
||||
// Toolbar/menu bar settings (not applicable if native menu bar is present)
|
||||
ui->toolsBox->setEnabled(!QMenuBar().isNativeMenuBar());
|
||||
#ifdef Q_OS_MACOS
|
||||
@ -261,8 +246,7 @@ void LauncherPage::loadSettings()
|
||||
|
||||
bool conversionOk = true;
|
||||
int fontSize = APPLICATION->settings()->get("ConsoleFontSize").toInt(&conversionOk);
|
||||
if(!conversionOk)
|
||||
{
|
||||
if (!conversionOk) {
|
||||
fontSize = 11;
|
||||
}
|
||||
ui->fontSizeBox->setValue(fontSize);
|
||||
@ -279,12 +263,9 @@ void LauncherPage::loadSettings()
|
||||
|
||||
QString sortMode = s->get("InstSortMode").toString();
|
||||
|
||||
if (sortMode == "LastLaunch")
|
||||
{
|
||||
if (sortMode == "LastLaunch") {
|
||||
ui->sortLastLaunchedBtn->setChecked(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ui->sortByNameBtn->setChecked(true);
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
/*
|
||||
* PolyMC - Minecraft Launcher
|
||||
* Prism Launcher - Minecraft Launcher
|
||||
* Copyright (c) 2022 Jamie Mansfield <jmansfield@cadixdev.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
@ -35,56 +35,41 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <QDialog>
|
||||
#include <memory>
|
||||
|
||||
#include "java/JavaChecker.h"
|
||||
#include "ui/pages/BasePage.h"
|
||||
#include <Application.h>
|
||||
#include "ui/ColorCache.h"
|
||||
#include <translations/TranslationsModel.h>
|
||||
#include "java/JavaChecker.h"
|
||||
#include "ui/ColorCache.h"
|
||||
#include "ui/pages/BasePage.h"
|
||||
|
||||
class QTextCharFormat;
|
||||
class SettingsObject;
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
namespace Ui {
|
||||
class LauncherPage;
|
||||
}
|
||||
|
||||
class LauncherPage : public QWidget, public BasePage
|
||||
{
|
||||
class LauncherPage : public QWidget, public BasePage {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit LauncherPage(QWidget *parent = 0);
|
||||
public:
|
||||
explicit LauncherPage(QWidget* parent = 0);
|
||||
~LauncherPage();
|
||||
|
||||
QString displayName() const override
|
||||
{
|
||||
return "Launcher";
|
||||
}
|
||||
QIcon icon() const override
|
||||
{
|
||||
return APPLICATION->getThemedIcon("launcher");
|
||||
}
|
||||
QString id() const override
|
||||
{
|
||||
return "launcher-settings";
|
||||
}
|
||||
QString helpPage() const override
|
||||
{
|
||||
return "Launcher-settings";
|
||||
}
|
||||
QString displayName() const override { return tr("Launcher"); }
|
||||
QIcon icon() const override { return APPLICATION->getThemedIcon("launcher"); }
|
||||
QString id() const override { return "launcher-settings"; }
|
||||
QString helpPage() const override { return "Launcher-settings"; }
|
||||
bool apply() override;
|
||||
void retranslate() override;
|
||||
|
||||
private:
|
||||
private:
|
||||
void applySettings();
|
||||
void loadSettings();
|
||||
|
||||
private
|
||||
slots:
|
||||
private slots:
|
||||
void on_instDirBrowseBtn_clicked();
|
||||
void on_modsDirBrowseBtn_clicked();
|
||||
void on_iconsDirBrowseBtn_clicked();
|
||||
@ -96,8 +81,8 @@ slots:
|
||||
*/
|
||||
void refreshFontPreview();
|
||||
|
||||
private:
|
||||
Ui::LauncherPage *ui;
|
||||
private:
|
||||
Ui::LauncherPage* ui;
|
||||
|
||||
/*!
|
||||
* Stores the currently selected update channel.
|
||||
@ -105,7 +90,7 @@ private:
|
||||
QString m_currentUpdateChannel;
|
||||
|
||||
// default format for the font preview...
|
||||
QTextCharFormat *defaultFormat;
|
||||
QTextCharFormat* defaultFormat;
|
||||
|
||||
std::unique_ptr<LogColorCache> m_colors;
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
/*
|
||||
* PolyMC - Minecraft Launcher
|
||||
* Prism Launcher - Minecraft Launcher
|
||||
* Copyright (c) 2022 Jamie Mansfield <jmansfield@cadixdev.org>
|
||||
* Copyright (C) 2023 seth <getchoo at tuta dot io>
|
||||
*
|
||||
@ -37,14 +37,14 @@
|
||||
#include "MinecraftPage.h"
|
||||
#include "ui_MinecraftPage.h"
|
||||
|
||||
#include <QMessageBox>
|
||||
#include <QDir>
|
||||
#include <QMessageBox>
|
||||
#include <QTabBar>
|
||||
|
||||
#include "settings/SettingsObject.h"
|
||||
#include "Application.h"
|
||||
#include "settings/SettingsObject.h"
|
||||
|
||||
MinecraftPage::MinecraftPage(QWidget *parent) : QWidget(parent), ui(new Ui::MinecraftPage)
|
||||
MinecraftPage::MinecraftPage(QWidget* parent) : QWidget(parent), ui(new Ui::MinecraftPage)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
loadSettings();
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
/*
|
||||
* PolyMC - Minecraft Launcher
|
||||
* Prism Launcher - Minecraft Launcher
|
||||
* Copyright (c) 2022 Jamie Mansfield <jmansfield@cadixdev.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
@ -35,57 +35,41 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <QDialog>
|
||||
#include <memory>
|
||||
|
||||
#include <Application.h>
|
||||
#include "java/JavaChecker.h"
|
||||
#include "ui/pages/BasePage.h"
|
||||
#include <Application.h>
|
||||
|
||||
class SettingsObject;
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
namespace Ui {
|
||||
class MinecraftPage;
|
||||
}
|
||||
|
||||
class MinecraftPage : public QWidget, public BasePage
|
||||
{
|
||||
class MinecraftPage : public QWidget, public BasePage {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MinecraftPage(QWidget *parent = 0);
|
||||
public:
|
||||
explicit MinecraftPage(QWidget* parent = 0);
|
||||
~MinecraftPage();
|
||||
|
||||
QString displayName() const override
|
||||
{
|
||||
return tr("Minecraft");
|
||||
}
|
||||
QIcon icon() const override
|
||||
{
|
||||
return APPLICATION->getThemedIcon("minecraft");
|
||||
}
|
||||
QString id() const override
|
||||
{
|
||||
return "minecraft-settings";
|
||||
}
|
||||
QString helpPage() const override
|
||||
{
|
||||
return "Minecraft-settings";
|
||||
}
|
||||
QString displayName() const override { return tr("Minecraft"); }
|
||||
QIcon icon() const override { return APPLICATION->getThemedIcon("minecraft"); }
|
||||
QString id() const override { return "minecraft-settings"; }
|
||||
QString helpPage() const override { return "Minecraft-settings"; }
|
||||
bool apply() override;
|
||||
void retranslate() override;
|
||||
|
||||
private:
|
||||
private:
|
||||
void updateCheckboxStuff();
|
||||
void applySettings();
|
||||
void loadSettings();
|
||||
|
||||
private
|
||||
slots:
|
||||
private slots:
|
||||
void on_maximizedCheckBox_clicked(bool checked);
|
||||
|
||||
private:
|
||||
Ui::MinecraftPage *ui;
|
||||
|
||||
private:
|
||||
Ui::MinecraftPage* ui;
|
||||
};
|
||||
|
@ -39,7 +39,7 @@
|
||||
</property>
|
||||
<widget class="QWidget" name="minecraftTab">
|
||||
<attribute name="title">
|
||||
<string notr="true">General</string>
|
||||
<string>General</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
/*
|
||||
* PolyMC - Minecraft Launcher
|
||||
* Prism Launcher - Minecraft Launcher
|
||||
* Copyright (c) 2022 Jamie Mansfield <jmansfield@cadixdev.org>
|
||||
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
|
||||
*
|
||||
@ -40,18 +40,17 @@
|
||||
#include <QButtonGroup>
|
||||
#include <QTabBar>
|
||||
|
||||
#include "settings/SettingsObject.h"
|
||||
#include "Application.h"
|
||||
#include "settings/SettingsObject.h"
|
||||
|
||||
ProxyPage::ProxyPage(QWidget *parent) : QWidget(parent), ui(new Ui::ProxyPage)
|
||||
ProxyPage::ProxyPage(QWidget* parent) : QWidget(parent), ui(new Ui::ProxyPage)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->tabWidget->tabBar()->hide();
|
||||
loadSettings();
|
||||
updateCheckboxStuff();
|
||||
|
||||
connect(ui->proxyGroup, QOverload<QAbstractButton *>::of(&QButtonGroup::buttonClicked),
|
||||
this, &ProxyPage::proxyGroupChanged);
|
||||
connect(ui->proxyGroup, QOverload<QAbstractButton*>::of(&QButtonGroup::buttonClicked), this, &ProxyPage::proxyGroupChanged);
|
||||
}
|
||||
|
||||
ProxyPage::~ProxyPage()
|
||||
@ -67,13 +66,12 @@ bool ProxyPage::apply()
|
||||
|
||||
void ProxyPage::updateCheckboxStuff()
|
||||
{
|
||||
bool enableEditing = ui->proxyHTTPBtn->isChecked()
|
||||
|| ui->proxySOCKS5Btn->isChecked();
|
||||
bool enableEditing = ui->proxyHTTPBtn->isChecked() || ui->proxySOCKS5Btn->isChecked();
|
||||
ui->proxyAddrBox->setEnabled(enableEditing);
|
||||
ui->proxyAuthBox->setEnabled(enableEditing);
|
||||
}
|
||||
|
||||
void ProxyPage::proxyGroupChanged(QAbstractButton *button)
|
||||
void ProxyPage::proxyGroupChanged(QAbstractButton* button)
|
||||
{
|
||||
updateCheckboxStuff();
|
||||
}
|
||||
@ -99,13 +97,8 @@ void ProxyPage::applySettings()
|
||||
s->set("ProxyUser", ui->proxyUserEdit->text());
|
||||
s->set("ProxyPass", ui->proxyPassEdit->text());
|
||||
|
||||
APPLICATION->updateProxySettings(
|
||||
proxyType,
|
||||
ui->proxyAddrEdit->text(),
|
||||
ui->proxyPortEdit->value(),
|
||||
ui->proxyUserEdit->text(),
|
||||
ui->proxyPassEdit->text()
|
||||
);
|
||||
APPLICATION->updateProxySettings(proxyType, ui->proxyAddrEdit->text(), ui->proxyPortEdit->value(), ui->proxyUserEdit->text(),
|
||||
ui->proxyPassEdit->text());
|
||||
}
|
||||
void ProxyPage::loadSettings()
|
||||
{
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
/*
|
||||
* PolyMC - Minecraft Launcher
|
||||
* Prism Launcher - Minecraft Launcher
|
||||
* Copyright (c) 2022 Jamie Mansfield <jmansfield@cadixdev.org>
|
||||
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
|
||||
*
|
||||
@ -36,53 +36,39 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <QAbstractButton>
|
||||
#include <QDialog>
|
||||
#include <memory>
|
||||
|
||||
#include "ui/pages/BasePage.h"
|
||||
#include <Application.h>
|
||||
#include "ui/pages/BasePage.h"
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
namespace Ui {
|
||||
class ProxyPage;
|
||||
}
|
||||
|
||||
class ProxyPage : public QWidget, public BasePage
|
||||
{
|
||||
class ProxyPage : public QWidget, public BasePage {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ProxyPage(QWidget *parent = 0);
|
||||
public:
|
||||
explicit ProxyPage(QWidget* parent = 0);
|
||||
~ProxyPage();
|
||||
|
||||
QString displayName() const override
|
||||
{
|
||||
return tr("Proxy");
|
||||
}
|
||||
QIcon icon() const override
|
||||
{
|
||||
return APPLICATION->getThemedIcon("proxy");
|
||||
}
|
||||
QString id() const override
|
||||
{
|
||||
return "proxy-settings";
|
||||
}
|
||||
QString helpPage() const override
|
||||
{
|
||||
return "Proxy-settings";
|
||||
}
|
||||
QString displayName() const override { return tr("Proxy"); }
|
||||
QIcon icon() const override { return APPLICATION->getThemedIcon("proxy"); }
|
||||
QString id() const override { return "proxy-settings"; }
|
||||
QString helpPage() const override { return "Proxy-settings"; }
|
||||
bool apply() override;
|
||||
void retranslate() override;
|
||||
|
||||
private slots:
|
||||
void proxyGroupChanged(QAbstractButton *button);
|
||||
private slots:
|
||||
void proxyGroupChanged(QAbstractButton* button);
|
||||
|
||||
private:
|
||||
private:
|
||||
void updateCheckboxStuff();
|
||||
void applySettings();
|
||||
void loadSettings();
|
||||
|
||||
private:
|
||||
Ui::ProxyPage *ui;
|
||||
private:
|
||||
Ui::ProxyPage* ui;
|
||||
};
|
||||
|
@ -4,8 +4,8 @@
|
||||
#include <QSortFilterProxyModel>
|
||||
|
||||
#include "Application.h"
|
||||
#include "settings/Setting.h"
|
||||
#include "minecraft/MinecraftInstance.h"
|
||||
#include "settings/Setting.h"
|
||||
#include "ui/pages/BasePage.h"
|
||||
|
||||
class ResourceFolderModel;
|
||||
@ -52,7 +52,7 @@ class ExternalResourcesPage : public QMainWindow, public BasePage {
|
||||
|
||||
virtual void addItem();
|
||||
void removeItem();
|
||||
virtual void removeItems(const QItemSelection &selection);
|
||||
virtual void removeItems(const QItemSelection& selection);
|
||||
|
||||
virtual void enableItem();
|
||||
virtual void disableItem();
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
/*
|
||||
* PolyMC - Minecraft Launcher
|
||||
* Prism Launcher - Minecraft Launcher
|
||||
* Copyright (c) 2022 Jamie Mansfield <jmansfield@cadixdev.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
@ -34,23 +34,20 @@
|
||||
*/
|
||||
|
||||
#include "GameOptionsPage.h"
|
||||
#include "ui_GameOptionsPage.h"
|
||||
#include "minecraft/MinecraftInstance.h"
|
||||
#include "minecraft/gameoptions/GameOptions.h"
|
||||
#include "ui_GameOptionsPage.h"
|
||||
|
||||
GameOptionsPage::GameOptionsPage(MinecraftInstance * inst, QWidget* parent)
|
||||
: QWidget(parent), ui(new Ui::GameOptionsPage)
|
||||
GameOptionsPage::GameOptionsPage(MinecraftInstance* inst, QWidget* parent) : QWidget(parent), ui(new Ui::GameOptionsPage)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->tabWidget->tabBar()->hide();
|
||||
m_model = inst->gameOptionsModel();
|
||||
ui->optionsView->setModel(m_model.get());
|
||||
auto head = ui->optionsView->header();
|
||||
if(head->count())
|
||||
{
|
||||
if (head->count()) {
|
||||
head->setSectionResizeMode(0, QHeaderView::ResizeToContents);
|
||||
for(int i = 1; i < head->count(); i++)
|
||||
{
|
||||
for (int i = 1; i < head->count(); i++) {
|
||||
head->setSectionResizeMode(i, QHeaderView::Stretch);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
/*
|
||||
* PolyMC - Minecraft Launcher
|
||||
* Prism Launcher - Minecraft Launcher
|
||||
* Copyright (c) 2022 Jamie Mansfield <jmansfield@cadixdev.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
@ -35,50 +35,36 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
#include <QString>
|
||||
#include <QWidget>
|
||||
|
||||
#include "ui/pages/BasePage.h"
|
||||
#include <Application.h>
|
||||
#include "ui/pages/BasePage.h"
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
namespace Ui {
|
||||
class GameOptionsPage;
|
||||
}
|
||||
|
||||
class GameOptions;
|
||||
class MinecraftInstance;
|
||||
|
||||
class GameOptionsPage : public QWidget, public BasePage
|
||||
{
|
||||
class GameOptionsPage : public QWidget, public BasePage {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit GameOptionsPage(MinecraftInstance *inst, QWidget *parent = 0);
|
||||
public:
|
||||
explicit GameOptionsPage(MinecraftInstance* inst, QWidget* parent = 0);
|
||||
virtual ~GameOptionsPage();
|
||||
|
||||
void openedImpl() override;
|
||||
void closedImpl() override;
|
||||
|
||||
virtual QString displayName() const override
|
||||
{
|
||||
return tr("Game Options");
|
||||
}
|
||||
virtual QIcon icon() const override
|
||||
{
|
||||
return APPLICATION->getThemedIcon("settings");
|
||||
}
|
||||
virtual QString id() const override
|
||||
{
|
||||
return "gameoptions";
|
||||
}
|
||||
virtual QString helpPage() const override
|
||||
{
|
||||
return "Game-Options-management";
|
||||
}
|
||||
virtual QString displayName() const override { return tr("Game Options"); }
|
||||
virtual QIcon icon() const override { return APPLICATION->getThemedIcon("settings"); }
|
||||
virtual QString id() const override { return "gameoptions"; }
|
||||
virtual QString helpPage() const override { return "Game-Options-management"; }
|
||||
void retranslate() override;
|
||||
|
||||
private: // data
|
||||
Ui::GameOptionsPage *ui = nullptr;
|
||||
private: // data
|
||||
Ui::GameOptionsPage* ui = nullptr;
|
||||
std::shared_ptr<GameOptions> m_model;
|
||||
};
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
/*
|
||||
* PolyMC - Minecraft Launcher
|
||||
* Prism Launcher - Minecraft Launcher
|
||||
* Copyright (c) 2022 Jamie Mansfield <jmansfield@cadixdev.org>
|
||||
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
|
||||
* Copyright (C) 2023 seth <getchoo at tuta dot io>
|
||||
@ -38,8 +38,8 @@
|
||||
#include "InstanceSettingsPage.h"
|
||||
#include "ui_InstanceSettingsPage.h"
|
||||
|
||||
#include <QFileDialog>
|
||||
#include <QDialog>
|
||||
#include <QFileDialog>
|
||||
#include <QMessageBox>
|
||||
|
||||
#include <sys.h>
|
||||
@ -47,15 +47,15 @@
|
||||
#include "ui/dialogs/VersionSelectDialog.h"
|
||||
#include "ui/widgets/CustomCommands.h"
|
||||
|
||||
#include "JavaCommon.h"
|
||||
#include "Application.h"
|
||||
#include "JavaCommon.h"
|
||||
#include "minecraft/auth/AccountList.h"
|
||||
|
||||
#include "FileSystem.h"
|
||||
#include "java/JavaInstallList.h"
|
||||
#include "java/JavaUtils.h"
|
||||
|
||||
InstanceSettingsPage::InstanceSettingsPage(BaseInstance *inst, QWidget *parent)
|
||||
InstanceSettingsPage::InstanceSettingsPage(BaseInstance* inst, QWidget* parent)
|
||||
: QWidget(parent), ui(new Ui::InstanceSettingsPage), m_instance(inst)
|
||||
{
|
||||
m_settings = inst->settings();
|
||||
@ -78,7 +78,7 @@ InstanceSettingsPage::~InstanceSettingsPage()
|
||||
|
||||
void InstanceSettingsPage::globalSettingsButtonClicked(bool)
|
||||
{
|
||||
switch(ui->settingsTabs->currentIndex()) {
|
||||
switch (ui->settingsTabs->currentIndex()) {
|
||||
case 0:
|
||||
APPLICATION->ShowGlobalSettings(this, "java-settings");
|
||||
return;
|
||||
@ -104,13 +104,10 @@ void InstanceSettingsPage::applySettings()
|
||||
// Miscellaneous
|
||||
bool miscellaneous = ui->miscellaneousSettingsBox->isChecked();
|
||||
m_settings->set("OverrideMiscellaneous", miscellaneous);
|
||||
if (miscellaneous)
|
||||
{
|
||||
if (miscellaneous) {
|
||||
m_settings->set("CloseAfterLaunch", ui->closeAfterLaunchCheck->isChecked());
|
||||
m_settings->set("QuitAfterGameStop", ui->quitAfterGameStopCheck->isChecked());
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
m_settings->reset("CloseAfterLaunch");
|
||||
m_settings->reset("QuitAfterGameStop");
|
||||
}
|
||||
@ -118,14 +115,11 @@ void InstanceSettingsPage::applySettings()
|
||||
// Console
|
||||
bool console = ui->consoleSettingsBox->isChecked();
|
||||
m_settings->set("OverrideConsole", console);
|
||||
if (console)
|
||||
{
|
||||
if (console) {
|
||||
m_settings->set("ShowConsole", ui->showConsoleCheck->isChecked());
|
||||
m_settings->set("AutoCloseConsole", ui->autoCloseConsoleCheck->isChecked());
|
||||
m_settings->set("ShowConsoleOnError", ui->showConsoleErrorCheck->isChecked());
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
m_settings->reset("ShowConsole");
|
||||
m_settings->reset("AutoCloseConsole");
|
||||
m_settings->reset("ShowConsoleOnError");
|
||||
@ -134,14 +128,11 @@ void InstanceSettingsPage::applySettings()
|
||||
// Window Size
|
||||
bool window = ui->windowSizeGroupBox->isChecked();
|
||||
m_settings->set("OverrideWindow", window);
|
||||
if (window)
|
||||
{
|
||||
if (window) {
|
||||
m_settings->set("LaunchMaximized", ui->maximizedCheckBox->isChecked());
|
||||
m_settings->set("MinecraftWinWidth", ui->windowWidthSpinBox->value());
|
||||
m_settings->set("MinecraftWinHeight", ui->windowHeightSpinBox->value());
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
m_settings->reset("LaunchMaximized");
|
||||
m_settings->reset("MinecraftWinWidth");
|
||||
m_settings->reset("MinecraftWinHeight");
|
||||
@ -150,24 +141,18 @@ void InstanceSettingsPage::applySettings()
|
||||
// Memory
|
||||
bool memory = ui->memoryGroupBox->isChecked();
|
||||
m_settings->set("OverrideMemory", memory);
|
||||
if (memory)
|
||||
{
|
||||
if (memory) {
|
||||
int min = ui->minMemSpinBox->value();
|
||||
int max = ui->maxMemSpinBox->value();
|
||||
if(min < max)
|
||||
{
|
||||
if (min < max) {
|
||||
m_settings->set("MinMemAlloc", min);
|
||||
m_settings->set("MaxMemAlloc", max);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
m_settings->set("MinMemAlloc", max);
|
||||
m_settings->set("MaxMemAlloc", min);
|
||||
}
|
||||
m_settings->set("PermGen", ui->permGenSpinBox->value());
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
m_settings->reset("MinMemAlloc");
|
||||
m_settings->reset("MaxMemAlloc");
|
||||
m_settings->reset("PermGen");
|
||||
@ -176,13 +161,10 @@ void InstanceSettingsPage::applySettings()
|
||||
// Java Install Settings
|
||||
bool javaInstall = ui->javaSettingsGroupBox->isChecked();
|
||||
m_settings->set("OverrideJavaLocation", javaInstall);
|
||||
if (javaInstall)
|
||||
{
|
||||
if (javaInstall) {
|
||||
m_settings->set("JavaPath", ui->javaPathTextBox->text());
|
||||
m_settings->set("IgnoreJavaCompatibility", ui->skipCompatibilityCheckbox->isChecked());
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
m_settings->reset("JavaPath");
|
||||
m_settings->reset("IgnoreJavaCompatibility");
|
||||
}
|
||||
@ -190,12 +172,9 @@ void InstanceSettingsPage::applySettings()
|
||||
// Java arguments
|
||||
bool javaArgs = ui->javaArgumentsGroupBox->isChecked();
|
||||
m_settings->set("OverrideJavaArgs", javaArgs);
|
||||
if(javaArgs)
|
||||
{
|
||||
if (javaArgs) {
|
||||
m_settings->set("JvmArgs", ui->jvmArgsTextBox->toPlainText().replace("\n", " "));
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
m_settings->reset("JvmArgs");
|
||||
}
|
||||
|
||||
@ -205,14 +184,11 @@ void InstanceSettingsPage::applySettings()
|
||||
// Custom Commands
|
||||
bool custcmd = ui->customCommands->checked();
|
||||
m_settings->set("OverrideCommands", custcmd);
|
||||
if (custcmd)
|
||||
{
|
||||
if (custcmd) {
|
||||
m_settings->set("PreLaunchCommand", ui->customCommands->prelaunchCommand());
|
||||
m_settings->set("WrapperCommand", ui->customCommands->wrapperCommand());
|
||||
m_settings->set("PostExitCommand", ui->customCommands->postexitCommand());
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
m_settings->reset("PreLaunchCommand");
|
||||
m_settings->reset("WrapperCommand");
|
||||
m_settings->reset("PostExitCommand");
|
||||
@ -221,13 +197,10 @@ void InstanceSettingsPage::applySettings()
|
||||
// Workarounds
|
||||
bool workarounds = ui->nativeWorkaroundsGroupBox->isChecked();
|
||||
m_settings->set("OverrideNativeWorkarounds", workarounds);
|
||||
if(workarounds)
|
||||
{
|
||||
if (workarounds) {
|
||||
m_settings->set("UseNativeOpenAL", ui->useNativeOpenALCheck->isChecked());
|
||||
m_settings->set("UseNativeGLFW", ui->useNativeGLFWCheck->isChecked());
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
m_settings->reset("UseNativeOpenAL");
|
||||
m_settings->reset("UseNativeGLFW");
|
||||
}
|
||||
@ -235,14 +208,11 @@ void InstanceSettingsPage::applySettings()
|
||||
// Performance
|
||||
bool performance = ui->perfomanceGroupBox->isChecked();
|
||||
m_settings->set("OverridePerformance", performance);
|
||||
if(performance)
|
||||
{
|
||||
if (performance) {
|
||||
m_settings->set("EnableFeralGamemode", ui->enableFeralGamemodeCheck->isChecked());
|
||||
m_settings->set("EnableMangoHud", ui->enableMangoHud->isChecked());
|
||||
m_settings->set("UseDiscreteGpu", ui->useDiscreteGpuCheck->isChecked());
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
m_settings->reset("EnableFeralGamemode");
|
||||
m_settings->reset("EnableMangoHud");
|
||||
m_settings->reset("UseDiscreteGpu");
|
||||
@ -251,13 +221,10 @@ void InstanceSettingsPage::applySettings()
|
||||
// Game time
|
||||
bool gameTime = ui->gameTimeGroupBox->isChecked();
|
||||
m_settings->set("OverrideGameTime", gameTime);
|
||||
if (gameTime)
|
||||
{
|
||||
if (gameTime) {
|
||||
m_settings->set("ShowGameTime", ui->showGameTime->isChecked());
|
||||
m_settings->set("RecordGameTime", ui->recordGameTime->isChecked());
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
m_settings->reset("ShowGameTime");
|
||||
m_settings->reset("RecordGameTime");
|
||||
}
|
||||
@ -265,12 +232,9 @@ void InstanceSettingsPage::applySettings()
|
||||
// Join server on launch
|
||||
bool joinServerOnLaunch = ui->serverJoinGroupBox->isChecked();
|
||||
m_settings->set("JoinServerOnLaunch", joinServerOnLaunch);
|
||||
if (joinServerOnLaunch)
|
||||
{
|
||||
if (joinServerOnLaunch) {
|
||||
m_settings->set("JoinServerOnLaunchAddress", ui->serverJoinAddress->text());
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
m_settings->reset("JoinServerOnLaunchAddress");
|
||||
}
|
||||
|
||||
@ -316,13 +280,10 @@ void InstanceSettingsPage::loadSettings()
|
||||
ui->memoryGroupBox->setChecked(m_settings->get("OverrideMemory").toBool());
|
||||
int min = m_settings->get("MinMemAlloc").toInt();
|
||||
int max = m_settings->get("MaxMemAlloc").toInt();
|
||||
if(min < max)
|
||||
{
|
||||
if (min < max) {
|
||||
ui->minMemSpinBox->setValue(min);
|
||||
ui->maxMemSpinBox->setValue(max);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ui->minMemSpinBox->setValue(max);
|
||||
ui->maxMemSpinBox->setValue(min);
|
||||
}
|
||||
@ -332,7 +293,6 @@ void InstanceSettingsPage::loadSettings()
|
||||
ui->labelPermGen->setVisible(permGenVisible);
|
||||
ui->labelPermgenNote->setVisible(permGenVisible);
|
||||
|
||||
|
||||
// Java Settings
|
||||
bool overrideJava = m_settings->get("OverrideJava").toBool();
|
||||
bool overrideLocation = m_settings->get("OverrideJavaLocation").toBool() || overrideJava;
|
||||
@ -346,13 +306,8 @@ void InstanceSettingsPage::loadSettings()
|
||||
ui->jvmArgsTextBox->setPlainText(m_settings->get("JvmArgs").toString());
|
||||
|
||||
// Custom commands
|
||||
ui->customCommands->initialize(
|
||||
true,
|
||||
m_settings->get("OverrideCommands").toBool(),
|
||||
m_settings->get("PreLaunchCommand").toString(),
|
||||
m_settings->get("WrapperCommand").toString(),
|
||||
m_settings->get("PostExitCommand").toString()
|
||||
);
|
||||
ui->customCommands->initialize(true, m_settings->get("OverrideCommands").toBool(), m_settings->get("PreLaunchCommand").toString(),
|
||||
m_settings->get("WrapperCommand").toString(), m_settings->get("PostExitCommand").toString());
|
||||
|
||||
// Workarounds
|
||||
ui->nativeWorkaroundsGroupBox->setChecked(m_settings->get("OverrideNativeWorkarounds").toBool());
|
||||
@ -408,8 +363,7 @@ void InstanceSettingsPage::on_javaDetectBtn_clicked()
|
||||
vselect.setResizeOn(2);
|
||||
vselect.exec();
|
||||
|
||||
if (vselect.result() == QDialog::Accepted && vselect.selectedVersion())
|
||||
{
|
||||
if (vselect.result() == QDialog::Accepted && vselect.selectedVersion()) {
|
||||
java = std::dynamic_pointer_cast<JavaInstall>(vselect.selectedVersion());
|
||||
ui->javaPathTextBox->setText(java->path);
|
||||
bool visible = java->id.requiresPermGen() && m_settings->get("OverrideMemory").toBool();
|
||||
@ -425,15 +379,13 @@ void InstanceSettingsPage::on_javaBrowseBtn_clicked()
|
||||
QString raw_path = QFileDialog::getOpenFileName(this, tr("Find Java executable"));
|
||||
|
||||
// do not allow current dir - it's dirty. Do not allow dirs that don't exist
|
||||
if(raw_path.isEmpty())
|
||||
{
|
||||
if (raw_path.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
QString cooked_path = FS::NormalizePath(raw_path);
|
||||
|
||||
QFileInfo javaInfo(cooked_path);
|
||||
if(!javaInfo.exists() || !javaInfo.isExecutable())
|
||||
{
|
||||
if (!javaInfo.exists() || !javaInfo.isExecutable()) {
|
||||
return;
|
||||
}
|
||||
ui->javaPathTextBox->setText(cooked_path);
|
||||
@ -447,13 +399,11 @@ void InstanceSettingsPage::on_javaBrowseBtn_clicked()
|
||||
|
||||
void InstanceSettingsPage::on_javaTestBtn_clicked()
|
||||
{
|
||||
if(checker)
|
||||
{
|
||||
if (checker) {
|
||||
return;
|
||||
}
|
||||
checker.reset(new JavaCommon::TestCheck(
|
||||
this, ui->javaPathTextBox->text(), ui->jvmArgsTextBox->toPlainText().replace("\n", " "),
|
||||
ui->minMemSpinBox->value(), ui->maxMemSpinBox->value(), ui->permGenSpinBox->value()));
|
||||
checker.reset(new JavaCommon::TestCheck(this, ui->javaPathTextBox->text(), ui->jvmArgsTextBox->toPlainText().replace("\n", " "),
|
||||
ui->minMemSpinBox->value(), ui->maxMemSpinBox->value(), ui->permGenSpinBox->value()));
|
||||
connect(checker.get(), SIGNAL(finished()), SLOT(checkerFinished()));
|
||||
checker->run();
|
||||
}
|
||||
@ -470,7 +420,6 @@ void InstanceSettingsPage::updateAccountsMenu()
|
||||
if (i == accountIndex)
|
||||
ui->instanceAccountSelector->setCurrentIndex(i);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
QIcon InstanceSettingsPage::getFaceForAccount(MinecraftAccountPtr account)
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
/*
|
||||
* PolyMC - Minecraft Launcher
|
||||
* Prism Launcher - Minecraft Launcher
|
||||
* Copyright (c) 2022 Jamie Mansfield <jmansfield@cadixdev.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
@ -46,35 +46,21 @@
|
||||
#include "ui/pages/BasePage.h"
|
||||
|
||||
class JavaChecker;
|
||||
namespace Ui
|
||||
{
|
||||
namespace Ui {
|
||||
class InstanceSettingsPage;
|
||||
}
|
||||
|
||||
class InstanceSettingsPage : public QWidget, public BasePage
|
||||
{
|
||||
class InstanceSettingsPage : public QWidget, public BasePage {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit InstanceSettingsPage(BaseInstance *inst, QWidget *parent = 0);
|
||||
public:
|
||||
explicit InstanceSettingsPage(BaseInstance* inst, QWidget* parent = 0);
|
||||
virtual ~InstanceSettingsPage();
|
||||
virtual QString displayName() const override
|
||||
{
|
||||
return tr("Settings");
|
||||
}
|
||||
virtual QIcon icon() const override
|
||||
{
|
||||
return APPLICATION->getThemedIcon("instance-settings");
|
||||
}
|
||||
virtual QString id() const override
|
||||
{
|
||||
return "settings";
|
||||
}
|
||||
virtual QString displayName() const override { return tr("Settings"); }
|
||||
virtual QIcon icon() const override { return APPLICATION->getThemedIcon("instance-settings"); }
|
||||
virtual QString id() const override { return "settings"; }
|
||||
virtual bool apply() override;
|
||||
virtual QString helpPage() const override
|
||||
{
|
||||
return "Instance-settings";
|
||||
}
|
||||
virtual QString helpPage() const override { return "Instance-settings"; }
|
||||
void retranslate() override;
|
||||
|
||||
void updateThresholds();
|
||||
@ -96,9 +82,9 @@ public:
|
||||
QIcon getFaceForAccount(MinecraftAccountPtr account);
|
||||
void changeInstanceAccount(int index);
|
||||
|
||||
private:
|
||||
Ui::InstanceSettingsPage *ui;
|
||||
BaseInstance *m_instance;
|
||||
private:
|
||||
Ui::InstanceSettingsPage* ui;
|
||||
BaseInstance* m_instance;
|
||||
SettingsObjectPtr m_settings;
|
||||
unique_qobject_ptr<JavaCommon::TestCheck> checker;
|
||||
};
|
||||
|
@ -116,7 +116,7 @@
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="labelPermGen">
|
||||
<property name="text">
|
||||
<string notr="true">PermGen:</string>
|
||||
<string>PermGen:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -47,56 +47,42 @@
|
||||
#include "launch/LaunchTask.h"
|
||||
#include "settings/Setting.h"
|
||||
|
||||
#include "ui/GuiUtil.h"
|
||||
#include "ui/ColorCache.h"
|
||||
#include "ui/GuiUtil.h"
|
||||
|
||||
#include <BuildConfig.h>
|
||||
|
||||
class LogFormatProxyModel : public QIdentityProxyModel
|
||||
{
|
||||
public:
|
||||
LogFormatProxyModel(QObject* parent = nullptr) : QIdentityProxyModel(parent)
|
||||
class LogFormatProxyModel : public QIdentityProxyModel {
|
||||
public:
|
||||
LogFormatProxyModel(QObject* parent = nullptr) : QIdentityProxyModel(parent) {}
|
||||
QVariant data(const QModelIndex& index, int role) const override
|
||||
{
|
||||
}
|
||||
QVariant data(const QModelIndex &index, int role) const override
|
||||
{
|
||||
switch(role)
|
||||
{
|
||||
switch (role) {
|
||||
case Qt::FontRole:
|
||||
return m_font;
|
||||
case Qt::ForegroundRole:
|
||||
{
|
||||
MessageLevel::Enum level = (MessageLevel::Enum) QIdentityProxyModel::data(index, LogModel::LevelRole).toInt();
|
||||
case Qt::ForegroundRole: {
|
||||
MessageLevel::Enum level = (MessageLevel::Enum)QIdentityProxyModel::data(index, LogModel::LevelRole).toInt();
|
||||
return m_colors->getFront(level);
|
||||
}
|
||||
case Qt::BackgroundRole:
|
||||
{
|
||||
MessageLevel::Enum level = (MessageLevel::Enum) QIdentityProxyModel::data(index, LogModel::LevelRole).toInt();
|
||||
case Qt::BackgroundRole: {
|
||||
MessageLevel::Enum level = (MessageLevel::Enum)QIdentityProxyModel::data(index, LogModel::LevelRole).toInt();
|
||||
return m_colors->getBack(level);
|
||||
}
|
||||
default:
|
||||
return QIdentityProxyModel::data(index, role);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void setFont(QFont font)
|
||||
{
|
||||
m_font = font;
|
||||
}
|
||||
void setFont(QFont font) { m_font = font; }
|
||||
|
||||
void setColors(LogColorCache* colors)
|
||||
{
|
||||
m_colors.reset(colors);
|
||||
}
|
||||
void setColors(LogColorCache* colors) { m_colors.reset(colors); }
|
||||
|
||||
QModelIndex find(const QModelIndex &start, const QString &value, bool reverse) const
|
||||
QModelIndex find(const QModelIndex& start, const QString& value, bool reverse) const
|
||||
{
|
||||
QModelIndex parentIndex = parent(start);
|
||||
auto compare = [&](int r) -> QModelIndex
|
||||
{
|
||||
auto compare = [&](int r) -> QModelIndex {
|
||||
QModelIndex idx = index(r, start.column(), parentIndex);
|
||||
if (!idx.isValid() || idx == start)
|
||||
{
|
||||
if (!idx.isValid() || idx == start) {
|
||||
return QModelIndex();
|
||||
}
|
||||
QVariant v = data(idx, Qt::DisplayRole);
|
||||
@ -105,35 +91,28 @@ public:
|
||||
return idx;
|
||||
return QModelIndex();
|
||||
};
|
||||
if(reverse)
|
||||
{
|
||||
if (reverse) {
|
||||
int from = start.row();
|
||||
int to = 0;
|
||||
|
||||
for (int i = 0; i < 2; ++i)
|
||||
{
|
||||
for (int r = from; (r >= to); --r)
|
||||
{
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
for (int r = from; (r >= to); --r) {
|
||||
auto idx = compare(r);
|
||||
if(idx.isValid())
|
||||
if (idx.isValid())
|
||||
return idx;
|
||||
}
|
||||
// prepare for the next iteration
|
||||
from = rowCount() - 1;
|
||||
to = start.row();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
int from = start.row();
|
||||
int to = rowCount(parentIndex);
|
||||
|
||||
for (int i = 0; i < 2; ++i)
|
||||
{
|
||||
for (int r = from; (r < to); ++r)
|
||||
{
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
for (int r = from; (r < to); ++r) {
|
||||
auto idx = compare(r);
|
||||
if(idx.isValid())
|
||||
if (idx.isValid())
|
||||
return idx;
|
||||
}
|
||||
// prepare for the next iteration
|
||||
@ -143,13 +122,13 @@ public:
|
||||
}
|
||||
return QModelIndex();
|
||||
}
|
||||
private:
|
||||
|
||||
private:
|
||||
QFont m_font;
|
||||
std::unique_ptr<LogColorCache> m_colors;
|
||||
};
|
||||
|
||||
LogPage::LogPage(InstancePtr instance, QWidget *parent)
|
||||
: QWidget(parent), ui(new Ui::LogPage), m_instance(instance)
|
||||
LogPage::LogPage(InstancePtr instance, QWidget* parent) : QWidget(parent), ui(new Ui::LogPage), m_instance(instance)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->tabWidget->tabBar()->hide();
|
||||
@ -167,8 +146,7 @@ LogPage::LogPage(InstancePtr instance, QWidget *parent)
|
||||
QString fontFamily = APPLICATION->settings()->get("ConsoleFont").toString();
|
||||
bool conversionOk = false;
|
||||
int fontSize = APPLICATION->settings()->get("ConsoleFontSize").toInt(&conversionOk);
|
||||
if(!conversionOk)
|
||||
{
|
||||
if (!conversionOk) {
|
||||
fontSize = 11;
|
||||
}
|
||||
m_proxy->setFont(QFont(fontFamily, fontSize));
|
||||
@ -179,8 +157,7 @@ LogPage::LogPage(InstancePtr instance, QWidget *parent)
|
||||
// set up instance and launch process recognition
|
||||
{
|
||||
auto launchTask = m_instance->getLaunchTask();
|
||||
if(launchTask)
|
||||
{
|
||||
if (launchTask) {
|
||||
setInstanceLaunchTaskChanged(launchTask, true);
|
||||
}
|
||||
connect(m_instance.get(), &BaseInstance::launchTaskChanged, this, &LogPage::onInstanceLaunchTaskChanged);
|
||||
@ -202,30 +179,23 @@ LogPage::~LogPage()
|
||||
|
||||
void LogPage::modelStateToUI()
|
||||
{
|
||||
if(m_model->wrapLines())
|
||||
{
|
||||
if (m_model->wrapLines()) {
|
||||
ui->text->setWordWrap(true);
|
||||
ui->wrapCheckbox->setCheckState(Qt::Checked);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ui->text->setWordWrap(false);
|
||||
ui->wrapCheckbox->setCheckState(Qt::Unchecked);
|
||||
}
|
||||
if(m_model->suspended())
|
||||
{
|
||||
if (m_model->suspended()) {
|
||||
ui->trackLogCheckbox->setCheckState(Qt::Unchecked);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ui->trackLogCheckbox->setCheckState(Qt::Checked);
|
||||
}
|
||||
}
|
||||
|
||||
void LogPage::UIToModelState()
|
||||
{
|
||||
if(!m_model)
|
||||
{
|
||||
if (!m_model) {
|
||||
return;
|
||||
}
|
||||
m_model->setLineWrap(ui->wrapCheckbox->checkState() == Qt::Checked);
|
||||
@ -235,21 +205,15 @@ void LogPage::UIToModelState()
|
||||
void LogPage::setInstanceLaunchTaskChanged(shared_qobject_ptr<LaunchTask> proc, bool initial)
|
||||
{
|
||||
m_process = proc;
|
||||
if(m_process)
|
||||
{
|
||||
if (m_process) {
|
||||
m_model = proc->getLogModel();
|
||||
m_proxy->setSourceModel(m_model.get());
|
||||
if(initial)
|
||||
{
|
||||
if (initial) {
|
||||
modelStateToUI();
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
UIToModelState();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
m_proxy->setSourceModel(nullptr);
|
||||
m_model.reset();
|
||||
}
|
||||
@ -272,34 +236,25 @@ bool LogPage::shouldDisplay() const
|
||||
|
||||
void LogPage::on_btnPaste_clicked()
|
||||
{
|
||||
if(!m_model)
|
||||
if (!m_model)
|
||||
return;
|
||||
|
||||
//FIXME: turn this into a proper task and move the upload logic out of GuiUtil!
|
||||
m_model->append(
|
||||
MessageLevel::Launcher,
|
||||
QString("Log upload triggered at: %1").arg(
|
||||
QDateTime::currentDateTime().toString(Qt::RFC2822Date)
|
||||
)
|
||||
);
|
||||
// FIXME: turn this into a proper task and move the upload logic out of GuiUtil!
|
||||
m_model->append(MessageLevel::Launcher,
|
||||
QString("Log upload triggered at: %1").arg(QDateTime::currentDateTime().toString(Qt::RFC2822Date)));
|
||||
auto url = GuiUtil::uploadPaste(tr("Minecraft Log"), m_model->toPlainText(), this);
|
||||
if(!url.has_value())
|
||||
{
|
||||
if (!url.has_value()) {
|
||||
m_model->append(MessageLevel::Error, QString("Log upload canceled"));
|
||||
}
|
||||
else if (url->isNull())
|
||||
{
|
||||
} else if (url->isNull()) {
|
||||
m_model->append(MessageLevel::Error, QString("Log upload failed!"));
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
m_model->append(MessageLevel::Launcher, QString("Log uploaded to: %1").arg(url.value()));
|
||||
}
|
||||
}
|
||||
|
||||
void LogPage::on_btnCopy_clicked()
|
||||
{
|
||||
if(!m_model)
|
||||
if (!m_model)
|
||||
return;
|
||||
m_model->append(MessageLevel::Launcher, QString("Clipboard copy at: %1").arg(QDateTime::currentDateTime().toString(Qt::RFC2822Date)));
|
||||
GuiUtil::setClipboardText(m_model->toPlainText());
|
||||
@ -307,7 +262,7 @@ void LogPage::on_btnCopy_clicked()
|
||||
|
||||
void LogPage::on_btnClear_clicked()
|
||||
{
|
||||
if(!m_model)
|
||||
if (!m_model)
|
||||
return;
|
||||
m_model->clear();
|
||||
m_container->refreshContainer();
|
||||
@ -320,7 +275,7 @@ void LogPage::on_btnBottom_clicked()
|
||||
|
||||
void LogPage::on_trackLogCheckbox_clicked(bool checked)
|
||||
{
|
||||
if(!m_model)
|
||||
if (!m_model)
|
||||
return;
|
||||
m_model->suspend(!checked);
|
||||
}
|
||||
@ -328,7 +283,7 @@ void LogPage::on_trackLogCheckbox_clicked(bool checked)
|
||||
void LogPage::on_wrapCheckbox_clicked(bool checked)
|
||||
{
|
||||
ui->text->setWordWrap(checked);
|
||||
if(!m_model)
|
||||
if (!m_model)
|
||||
return;
|
||||
m_model->setLineWrap(checked);
|
||||
}
|
||||
@ -353,8 +308,7 @@ void LogPage::findPreviousActivated()
|
||||
void LogPage::findActivated()
|
||||
{
|
||||
// focus the search bar if it doesn't have focus
|
||||
if (!ui->searchBar->hasFocus())
|
||||
{
|
||||
if (!ui->searchBar->hasFocus()) {
|
||||
ui->searchBar->setFocus();
|
||||
ui->searchBar->selectAll();
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
/*
|
||||
* PolyMC - Minecraft Launcher
|
||||
* Prism Launcher - Minecraft Launcher
|
||||
* Copyright (c) 2022 Jamie Mansfield <jmansfield@cadixdev.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
@ -37,46 +37,32 @@
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#include <Application.h>
|
||||
#include "BaseInstance.h"
|
||||
#include "launch/LaunchTask.h"
|
||||
#include "ui/pages/BasePage.h"
|
||||
#include <Application.h>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
namespace Ui {
|
||||
class LogPage;
|
||||
}
|
||||
class QTextCharFormat;
|
||||
class LogFormatProxyModel;
|
||||
|
||||
class LogPage : public QWidget, public BasePage
|
||||
{
|
||||
class LogPage : public QWidget, public BasePage {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit LogPage(InstancePtr instance, QWidget *parent = 0);
|
||||
public:
|
||||
explicit LogPage(InstancePtr instance, QWidget* parent = 0);
|
||||
virtual ~LogPage();
|
||||
virtual QString displayName() const override
|
||||
{
|
||||
return tr("Minecraft Log");
|
||||
}
|
||||
virtual QIcon icon() const override
|
||||
{
|
||||
return APPLICATION->getThemedIcon("log");
|
||||
}
|
||||
virtual QString id() const override
|
||||
{
|
||||
return "console";
|
||||
}
|
||||
virtual QString displayName() const override { return tr("Minecraft Log"); }
|
||||
virtual QIcon icon() const override { return APPLICATION->getThemedIcon("log"); }
|
||||
virtual QString id() const override { return "console"; }
|
||||
virtual bool apply() override;
|
||||
virtual QString helpPage() const override
|
||||
{
|
||||
return "Minecraft-Logs";
|
||||
}
|
||||
virtual QString helpPage() const override { return "Minecraft-Logs"; }
|
||||
virtual bool shouldDisplay() const override;
|
||||
void retranslate() override;
|
||||
|
||||
private slots:
|
||||
private slots:
|
||||
void on_btnPaste_clicked();
|
||||
void on_btnCopy_clicked();
|
||||
void on_btnClear_clicked();
|
||||
@ -92,16 +78,16 @@ private slots:
|
||||
|
||||
void onInstanceLaunchTaskChanged(shared_qobject_ptr<LaunchTask> proc);
|
||||
|
||||
private:
|
||||
private:
|
||||
void modelStateToUI();
|
||||
void UIToModelState();
|
||||
void setInstanceLaunchTaskChanged(shared_qobject_ptr<LaunchTask> proc, bool initial);
|
||||
|
||||
private:
|
||||
Ui::LogPage *ui;
|
||||
private:
|
||||
Ui::LogPage* ui;
|
||||
InstancePtr m_instance;
|
||||
shared_qobject_ptr<LaunchTask> m_process;
|
||||
|
||||
LogFormatProxyModel * m_proxy;
|
||||
shared_qobject_ptr <LogModel> m_model;
|
||||
LogFormatProxyModel* m_proxy;
|
||||
shared_qobject_ptr<LogModel> m_model;
|
||||
};
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
/*
|
||||
* PolyMC - Minecraft Launcher
|
||||
* Prism Launcher - Minecraft Launcher
|
||||
* Copyright (c) 2022 Jamie Mansfield <jmansfield@cadixdev.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
@ -34,11 +34,10 @@
|
||||
*/
|
||||
|
||||
#include "NotesPage.h"
|
||||
#include "ui_NotesPage.h"
|
||||
#include <QTabBar>
|
||||
#include "ui_NotesPage.h"
|
||||
|
||||
NotesPage::NotesPage(BaseInstance *inst, QWidget *parent)
|
||||
: QWidget(parent), ui(new Ui::NotesPage), m_inst(inst)
|
||||
NotesPage::NotesPage(BaseInstance* inst, QWidget* parent) : QWidget(parent), ui(new Ui::NotesPage), m_inst(inst)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->noteEditor->setText(m_inst->notes());
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
/*
|
||||
* PolyMC - Minecraft Launcher
|
||||
* Prism Launcher - Minecraft Launcher
|
||||
* Copyright (c) 2022 Jamie Mansfield <jmansfield@cadixdev.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
@ -37,45 +37,34 @@
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#include <Application.h>
|
||||
#include "BaseInstance.h"
|
||||
#include "ui/pages/BasePage.h"
|
||||
#include <Application.h>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
namespace Ui {
|
||||
class NotesPage;
|
||||
}
|
||||
|
||||
class NotesPage : public QWidget, public BasePage
|
||||
{
|
||||
class NotesPage : public QWidget, public BasePage {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit NotesPage(BaseInstance *inst, QWidget *parent = 0);
|
||||
public:
|
||||
explicit NotesPage(BaseInstance* inst, QWidget* parent = 0);
|
||||
virtual ~NotesPage();
|
||||
virtual QString displayName() const override
|
||||
{
|
||||
return tr("Notes");
|
||||
}
|
||||
virtual QString displayName() const override { return tr("Notes"); }
|
||||
virtual QIcon icon() const override
|
||||
{
|
||||
auto icon = APPLICATION->getThemedIcon("notes");
|
||||
if(icon.isNull())
|
||||
if (icon.isNull())
|
||||
icon = APPLICATION->getThemedIcon("news");
|
||||
return icon;
|
||||
}
|
||||
virtual QString id() const override
|
||||
{
|
||||
return "notes";
|
||||
}
|
||||
virtual QString id() const override { return "notes"; }
|
||||
virtual bool apply() override;
|
||||
virtual QString helpPage() const override
|
||||
{
|
||||
return "Notes";
|
||||
}
|
||||
virtual QString helpPage() const override { return "Notes"; }
|
||||
void retranslate() override;
|
||||
|
||||
private:
|
||||
Ui::NotesPage *ui;
|
||||
BaseInstance *m_inst;
|
||||
private:
|
||||
Ui::NotesPage* ui;
|
||||
BaseInstance* m_inst;
|
||||
};
|
||||
|
@ -41,14 +41,13 @@
|
||||
|
||||
#include "ui/GuiUtil.h"
|
||||
|
||||
#include "RecursiveFileSystemWatcher.h"
|
||||
#include <GZip.h>
|
||||
#include <FileSystem.h>
|
||||
#include <GZip.h>
|
||||
#include <QShortcut>
|
||||
#include "RecursiveFileSystemWatcher.h"
|
||||
|
||||
OtherLogsPage::OtherLogsPage(QString path, IPathMatcher::Ptr fileFilter, QWidget *parent)
|
||||
: QWidget(parent), ui(new Ui::OtherLogsPage), m_path(path), m_fileFilter(fileFilter),
|
||||
m_watcher(new RecursiveFileSystemWatcher(this))
|
||||
OtherLogsPage::OtherLogsPage(QString path, IPathMatcher::Ptr fileFilter, QWidget* parent)
|
||||
: QWidget(parent), ui(new Ui::OtherLogsPage), m_path(path), m_fileFilter(fileFilter), m_watcher(new RecursiveFileSystemWatcher(this))
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->tabWidget->tabBar()->hide();
|
||||
@ -94,21 +93,15 @@ void OtherLogsPage::populateSelectLogBox()
|
||||
{
|
||||
ui->selectLogBox->clear();
|
||||
ui->selectLogBox->addItems(m_watcher->files());
|
||||
if (m_currentFile.isEmpty())
|
||||
{
|
||||
if (m_currentFile.isEmpty()) {
|
||||
setControlsEnabled(false);
|
||||
ui->selectLogBox->setCurrentIndex(-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
const int index = ui->selectLogBox->findText(m_currentFile);
|
||||
if (index != -1)
|
||||
{
|
||||
if (index != -1) {
|
||||
ui->selectLogBox->setCurrentIndex(index);
|
||||
setControlsEnabled(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
setControlsEnabled(false);
|
||||
}
|
||||
}
|
||||
@ -117,19 +110,15 @@ void OtherLogsPage::populateSelectLogBox()
|
||||
void OtherLogsPage::on_selectLogBox_currentIndexChanged(const int index)
|
||||
{
|
||||
QString file;
|
||||
if (index != -1)
|
||||
{
|
||||
if (index != -1) {
|
||||
file = ui->selectLogBox->itemText(index);
|
||||
}
|
||||
|
||||
if (file.isEmpty() || !QFile::exists(FS::PathCombine(m_path, file)))
|
||||
{
|
||||
if (file.isEmpty() || !QFile::exists(FS::PathCombine(m_path, file))) {
|
||||
m_currentFile = QString();
|
||||
ui->text->clear();
|
||||
setControlsEnabled(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
m_currentFile = file;
|
||||
on_btnReload_clicked();
|
||||
setControlsEnabled(true);
|
||||
@ -138,64 +127,49 @@ void OtherLogsPage::on_selectLogBox_currentIndexChanged(const int index)
|
||||
|
||||
void OtherLogsPage::on_btnReload_clicked()
|
||||
{
|
||||
if(m_currentFile.isEmpty())
|
||||
{
|
||||
if (m_currentFile.isEmpty()) {
|
||||
setControlsEnabled(false);
|
||||
return;
|
||||
}
|
||||
QFile file(FS::PathCombine(m_path, m_currentFile));
|
||||
if (!file.open(QFile::ReadOnly))
|
||||
{
|
||||
if (!file.open(QFile::ReadOnly)) {
|
||||
setControlsEnabled(false);
|
||||
ui->btnReload->setEnabled(true); // allow reload
|
||||
ui->btnReload->setEnabled(true); // allow reload
|
||||
m_currentFile = QString();
|
||||
QMessageBox::critical(this, tr("Error"), tr("Unable to open %1 for reading: %2")
|
||||
.arg(m_currentFile, file.errorString()));
|
||||
}
|
||||
else
|
||||
{
|
||||
auto setPlainText = [&](const QString & text)
|
||||
{
|
||||
QMessageBox::critical(this, tr("Error"), tr("Unable to open %1 for reading: %2").arg(m_currentFile, file.errorString()));
|
||||
} else {
|
||||
auto setPlainText = [&](const QString& text) {
|
||||
QString fontFamily = APPLICATION->settings()->get("ConsoleFont").toString();
|
||||
bool conversionOk = false;
|
||||
int fontSize = APPLICATION->settings()->get("ConsoleFontSize").toInt(&conversionOk);
|
||||
if(!conversionOk)
|
||||
{
|
||||
if (!conversionOk) {
|
||||
fontSize = 11;
|
||||
}
|
||||
QTextDocument *doc = ui->text->document();
|
||||
QTextDocument* doc = ui->text->document();
|
||||
doc->setDefaultFont(QFont(fontFamily, fontSize));
|
||||
ui->text->setPlainText(text);
|
||||
};
|
||||
auto showTooBig = [&]()
|
||||
{
|
||||
setPlainText(
|
||||
tr("The file (%1) is too big. You may want to open it in a viewer optimized "
|
||||
"for large files.").arg(file.fileName()));
|
||||
auto showTooBig = [&]() {
|
||||
setPlainText(tr("The file (%1) is too big. You may want to open it in a viewer optimized "
|
||||
"for large files.")
|
||||
.arg(file.fileName()));
|
||||
};
|
||||
if(file.size() > (1024ll * 1024ll * 12ll))
|
||||
{
|
||||
if (file.size() > (1024ll * 1024ll * 12ll)) {
|
||||
showTooBig();
|
||||
return;
|
||||
}
|
||||
QString content;
|
||||
if(file.fileName().endsWith(".gz"))
|
||||
{
|
||||
if (file.fileName().endsWith(".gz")) {
|
||||
QByteArray temp;
|
||||
if(!GZip::unzip(file.readAll(), temp))
|
||||
{
|
||||
setPlainText(
|
||||
tr("The file (%1) is not readable.").arg(file.fileName()));
|
||||
if (!GZip::unzip(file.readAll(), temp)) {
|
||||
setPlainText(tr("The file (%1) is not readable.").arg(file.fileName()));
|
||||
return;
|
||||
}
|
||||
content = QString::fromUtf8(temp);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
content = QString::fromUtf8(file.readAll());
|
||||
}
|
||||
if (content.size() >= 50000000ll)
|
||||
{
|
||||
if (content.size() >= 50000000ll) {
|
||||
showTooBig();
|
||||
return;
|
||||
}
|
||||
@ -215,8 +189,7 @@ void OtherLogsPage::on_btnCopy_clicked()
|
||||
|
||||
void OtherLogsPage::on_btnDelete_clicked()
|
||||
{
|
||||
if(m_currentFile.isEmpty())
|
||||
{
|
||||
if (m_currentFile.isEmpty()) {
|
||||
setControlsEnabled(false);
|
||||
return;
|
||||
}
|
||||
@ -230,36 +203,27 @@ void OtherLogsPage::on_btnDelete_clicked()
|
||||
}
|
||||
QFile file(FS::PathCombine(m_path, m_currentFile));
|
||||
|
||||
if (FS::trash(file.fileName()))
|
||||
{
|
||||
if (FS::trash(file.fileName())) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!file.remove())
|
||||
{
|
||||
QMessageBox::critical(this, tr("Error"), tr("Unable to delete %1: %2")
|
||||
.arg(m_currentFile, file.errorString()));
|
||||
if (!file.remove()) {
|
||||
QMessageBox::critical(this, tr("Error"), tr("Unable to delete %1: %2").arg(m_currentFile, file.errorString()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void OtherLogsPage::on_btnClean_clicked()
|
||||
{
|
||||
auto toDelete = m_watcher->files();
|
||||
if(toDelete.isEmpty())
|
||||
{
|
||||
if (toDelete.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
QMessageBox *messageBox = new QMessageBox(this);
|
||||
QMessageBox* messageBox = new QMessageBox(this);
|
||||
messageBox->setWindowTitle(tr("Confirm Cleanup"));
|
||||
if(toDelete.size() > 5)
|
||||
{
|
||||
if (toDelete.size() > 5) {
|
||||
messageBox->setText(tr("Are you sure you want to delete all log files?"));
|
||||
messageBox->setDetailedText(toDelete.join('\n'));
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
messageBox->setText(tr("Are you sure you want to delete all these files?\n%1").arg(toDelete.join('\n')));
|
||||
}
|
||||
messageBox->setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
|
||||
@ -268,34 +232,26 @@ void OtherLogsPage::on_btnClean_clicked()
|
||||
messageBox->setIcon(QMessageBox::Question);
|
||||
messageBox->setTextInteractionFlags(Qt::TextBrowserInteraction);
|
||||
|
||||
if (messageBox->exec() != QMessageBox::Ok)
|
||||
{
|
||||
if (messageBox->exec() != QMessageBox::Ok) {
|
||||
return;
|
||||
}
|
||||
QStringList failed;
|
||||
for(auto item: toDelete)
|
||||
{
|
||||
for (auto item : toDelete) {
|
||||
QFile file(FS::PathCombine(m_path, item));
|
||||
if (FS::trash(file.fileName()))
|
||||
{
|
||||
if (FS::trash(file.fileName())) {
|
||||
continue;
|
||||
}
|
||||
if (!file.remove())
|
||||
{
|
||||
if (!file.remove()) {
|
||||
failed.push_back(item);
|
||||
}
|
||||
}
|
||||
if(!failed.empty())
|
||||
{
|
||||
QMessageBox *messageBox = new QMessageBox(this);
|
||||
if (!failed.empty()) {
|
||||
QMessageBox* messageBox = new QMessageBox(this);
|
||||
messageBox->setWindowTitle(tr("Error"));
|
||||
if(failed.size() > 5)
|
||||
{
|
||||
if (failed.size() > 5) {
|
||||
messageBox->setText(tr("Couldn't delete some files!"));
|
||||
messageBox->setDetailedText(failed.join('\n'));
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
messageBox->setText(tr("Couldn't delete some files:\n%1").arg(failed.join('\n')));
|
||||
}
|
||||
messageBox->setStandardButtons(QMessageBox::Ok);
|
||||
@ -307,7 +263,6 @@ void OtherLogsPage::on_btnClean_clicked()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void OtherLogsPage::setControlsEnabled(const bool enabled)
|
||||
{
|
||||
ui->btnReload->setEnabled(enabled);
|
||||
@ -319,7 +274,7 @@ void OtherLogsPage::setControlsEnabled(const bool enabled)
|
||||
}
|
||||
|
||||
// FIXME: HACK, use LogView instead?
|
||||
static void findNext(QPlainTextEdit * _this, const QString& what, bool reverse)
|
||||
static void findNext(QPlainTextEdit* _this, const QString& what, bool reverse)
|
||||
{
|
||||
_this->find(what, reverse ? QTextDocument::FindFlag::FindBackward : QTextDocument::FindFlag(0));
|
||||
}
|
||||
@ -344,8 +299,7 @@ void OtherLogsPage::findPreviousActivated()
|
||||
void OtherLogsPage::findActivated()
|
||||
{
|
||||
// focus the search bar if it doesn't have focus
|
||||
if (!ui->searchBar->hasFocus())
|
||||
{
|
||||
if (!ui->searchBar->hasFocus()) {
|
||||
ui->searchBar->setFocus();
|
||||
ui->searchBar->selectAll();
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
/*
|
||||
* PolyMC - Minecraft Launcher
|
||||
* Prism Launcher - Minecraft Launcher
|
||||
* Copyright (c) 2022 Jamie Mansfield <jmansfield@cadixdev.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
@ -37,47 +37,33 @@
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#include "ui/pages/BasePage.h"
|
||||
#include <Application.h>
|
||||
#include <pathmatcher/IPathMatcher.h>
|
||||
#include "ui/pages/BasePage.h"
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
namespace Ui {
|
||||
class OtherLogsPage;
|
||||
}
|
||||
|
||||
class RecursiveFileSystemWatcher;
|
||||
|
||||
class OtherLogsPage : public QWidget, public BasePage
|
||||
{
|
||||
class OtherLogsPage : public QWidget, public BasePage {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit OtherLogsPage(QString path, IPathMatcher::Ptr fileFilter, QWidget *parent = 0);
|
||||
public:
|
||||
explicit OtherLogsPage(QString path, IPathMatcher::Ptr fileFilter, QWidget* parent = 0);
|
||||
~OtherLogsPage();
|
||||
|
||||
QString id() const override
|
||||
{
|
||||
return "logs";
|
||||
}
|
||||
QString displayName() const override
|
||||
{
|
||||
return tr("Other logs");
|
||||
}
|
||||
QIcon icon() const override
|
||||
{
|
||||
return APPLICATION->getThemedIcon("log");
|
||||
}
|
||||
QString helpPage() const override
|
||||
{
|
||||
return "Minecraft-Logs";
|
||||
}
|
||||
QString id() const override { return "logs"; }
|
||||
QString displayName() const override { return tr("Other logs"); }
|
||||
QIcon icon() const override { return APPLICATION->getThemedIcon("log"); }
|
||||
QString helpPage() const override { return "Minecraft-Logs"; }
|
||||
void retranslate() override;
|
||||
|
||||
void openedImpl() override;
|
||||
void closedImpl() override;
|
||||
|
||||
private slots:
|
||||
private slots:
|
||||
void populateSelectLogBox();
|
||||
void on_selectLogBox_currentIndexChanged(const int index);
|
||||
void on_btnReload_clicked();
|
||||
@ -91,13 +77,13 @@ private slots:
|
||||
void findNextActivated();
|
||||
void findPreviousActivated();
|
||||
|
||||
private:
|
||||
private:
|
||||
void setControlsEnabled(const bool enabled);
|
||||
|
||||
private:
|
||||
Ui::OtherLogsPage *ui;
|
||||
private:
|
||||
Ui::OtherLogsPage* ui;
|
||||
QString m_path;
|
||||
QString m_currentFile;
|
||||
IPathMatcher::Ptr m_fileFilter;
|
||||
RecursiveFileSystemWatcher *m_watcher;
|
||||
RecursiveFileSystemWatcher* m_watcher;
|
||||
};
|
||||
|
@ -42,11 +42,10 @@
|
||||
|
||||
#include "minecraft/mod/ResourcePackFolderModel.h"
|
||||
|
||||
class ResourcePackPage : public ExternalResourcesPage
|
||||
{
|
||||
class ResourcePackPage : public ExternalResourcesPage {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ResourcePackPage(MinecraftInstance *instance, std::shared_ptr<ResourcePackFolderModel> model, QWidget *parent = 0);
|
||||
public:
|
||||
explicit ResourcePackPage(MinecraftInstance* instance, std::shared_ptr<ResourcePackFolderModel> model, QWidget* parent = 0);
|
||||
|
||||
QString displayName() const override { return tr("Resource packs"); }
|
||||
QIcon icon() const override { return APPLICATION->getThemedIcon("resourcepacks"); }
|
||||
@ -55,12 +54,10 @@ public:
|
||||
|
||||
virtual bool shouldDisplay() const override
|
||||
{
|
||||
return !m_instance->traits().contains("no-texturepacks") &&
|
||||
!m_instance->traits().contains("texturepacks");
|
||||
return !m_instance->traits().contains("no-texturepacks") && !m_instance->traits().contains("texturepacks");
|
||||
}
|
||||
|
||||
public slots:
|
||||
bool onSelectionChanged(const QModelIndex& current, const QModelIndex& previous) override;
|
||||
void downloadRPs();
|
||||
};
|
||||
|
||||
|
@ -39,52 +39,50 @@
|
||||
#include "BuildConfig.h"
|
||||
#include "ui_ScreenshotsPage.h"
|
||||
|
||||
#include <QModelIndex>
|
||||
#include <QMutableListIterator>
|
||||
#include <QMap>
|
||||
#include <QSet>
|
||||
#include <QClipboard>
|
||||
#include <QEvent>
|
||||
#include <QFileIconProvider>
|
||||
#include <QFileSystemModel>
|
||||
#include <QStyledItemDelegate>
|
||||
#include <QLineEdit>
|
||||
#include <QEvent>
|
||||
#include <QPainter>
|
||||
#include <QClipboard>
|
||||
#include <QKeyEvent>
|
||||
#include <QLineEdit>
|
||||
#include <QMap>
|
||||
#include <QMenu>
|
||||
#include <QModelIndex>
|
||||
#include <QMutableListIterator>
|
||||
#include <QPainter>
|
||||
#include <QRegularExpression>
|
||||
#include <QSet>
|
||||
#include <QStyledItemDelegate>
|
||||
|
||||
#include <Application.h>
|
||||
|
||||
#include "ui/dialogs/ProgressDialog.h"
|
||||
#include "ui/dialogs/CustomMessageBox.h"
|
||||
#include "ui/dialogs/ProgressDialog.h"
|
||||
|
||||
#include "net/NetJob.h"
|
||||
#include "screenshots/ImgurUpload.h"
|
||||
#include "screenshots/ImgurAlbumCreation.h"
|
||||
#include "screenshots/ImgurUpload.h"
|
||||
#include "tasks/SequentialTask.h"
|
||||
|
||||
#include "RWStorage.h"
|
||||
#include <FileSystem.h>
|
||||
#include <DesktopServices.h>
|
||||
#include <FileSystem.h>
|
||||
#include "RWStorage.h"
|
||||
|
||||
typedef RWStorage<QString, QIcon> SharedIconCache;
|
||||
typedef std::shared_ptr<SharedIconCache> SharedIconCachePtr;
|
||||
|
||||
class ThumbnailingResult : public QObject
|
||||
{
|
||||
class ThumbnailingResult : public QObject {
|
||||
Q_OBJECT
|
||||
public slots:
|
||||
inline void emitResultsReady(const QString &path) { emit resultsReady(path); }
|
||||
inline void emitResultsFailed(const QString &path) { emit resultsFailed(path); }
|
||||
signals:
|
||||
void resultsReady(const QString &path);
|
||||
void resultsFailed(const QString &path);
|
||||
public slots:
|
||||
inline void emitResultsReady(const QString& path) { emit resultsReady(path); }
|
||||
inline void emitResultsFailed(const QString& path) { emit resultsFailed(path); }
|
||||
signals:
|
||||
void resultsReady(const QString& path);
|
||||
void resultsFailed(const QString& path);
|
||||
};
|
||||
|
||||
class ThumbnailRunnable : public QRunnable
|
||||
{
|
||||
public:
|
||||
class ThumbnailRunnable : public QRunnable {
|
||||
public:
|
||||
ThumbnailRunnable(QString path, SharedIconCachePtr cache)
|
||||
{
|
||||
m_path = path;
|
||||
@ -129,57 +127,50 @@ public:
|
||||
|
||||
// this is about as elegant and well written as a bag of bricks with scribbles done by insane
|
||||
// asylum patients.
|
||||
class FilterModel : public QIdentityProxyModel
|
||||
{
|
||||
class FilterModel : public QIdentityProxyModel {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit FilterModel(QObject *parent = 0) : QIdentityProxyModel(parent)
|
||||
public:
|
||||
explicit FilterModel(QObject* parent = 0) : QIdentityProxyModel(parent)
|
||||
{
|
||||
m_thumbnailingPool.setMaxThreadCount(4);
|
||||
m_thumbnailCache = std::make_shared<SharedIconCache>();
|
||||
m_thumbnailCache->add("placeholder", APPLICATION->getThemedIcon("screenshot-placeholder"));
|
||||
connect(&watcher, SIGNAL(fileChanged(QString)), SLOT(fileChanged(QString)));
|
||||
}
|
||||
virtual ~FilterModel() {
|
||||
virtual ~FilterModel()
|
||||
{
|
||||
m_thumbnailingPool.clear();
|
||||
if (!m_thumbnailingPool.waitForDone(500))
|
||||
qDebug() << "Thumbnail pool took longer than 500ms to finish";
|
||||
}
|
||||
virtual QVariant data(const QModelIndex &proxyIndex, int role = Qt::DisplayRole) const
|
||||
virtual QVariant data(const QModelIndex& proxyIndex, int role = Qt::DisplayRole) const
|
||||
{
|
||||
auto model = sourceModel();
|
||||
if (!model)
|
||||
return QVariant();
|
||||
if (role == Qt::DisplayRole || role == Qt::EditRole)
|
||||
{
|
||||
if (role == Qt::DisplayRole || role == Qt::EditRole) {
|
||||
QVariant result = sourceModel()->data(mapToSource(proxyIndex), role);
|
||||
return result.toString().remove(QRegularExpression("\\.png$"));
|
||||
}
|
||||
if (role == Qt::DecorationRole)
|
||||
{
|
||||
QVariant result =
|
||||
sourceModel()->data(mapToSource(proxyIndex), QFileSystemModel::FilePathRole);
|
||||
if (role == Qt::DecorationRole) {
|
||||
QVariant result = sourceModel()->data(mapToSource(proxyIndex), QFileSystemModel::FilePathRole);
|
||||
QString filePath = result.toString();
|
||||
QIcon temp;
|
||||
if (!watched.contains(filePath))
|
||||
{
|
||||
((QFileSystemWatcher &)watcher).addPath(filePath);
|
||||
((QSet<QString> &)watched).insert(filePath);
|
||||
if (!watched.contains(filePath)) {
|
||||
((QFileSystemWatcher&)watcher).addPath(filePath);
|
||||
((QSet<QString>&)watched).insert(filePath);
|
||||
}
|
||||
if (m_thumbnailCache->get(filePath, temp))
|
||||
{
|
||||
if (m_thumbnailCache->get(filePath, temp)) {
|
||||
return temp;
|
||||
}
|
||||
if (!m_failed.contains(filePath))
|
||||
{
|
||||
((FilterModel *)this)->thumbnailImage(filePath);
|
||||
if (!m_failed.contains(filePath)) {
|
||||
((FilterModel*)this)->thumbnailImage(filePath);
|
||||
}
|
||||
return (m_thumbnailCache->get("placeholder"));
|
||||
}
|
||||
return sourceModel()->data(mapToSource(proxyIndex), role);
|
||||
}
|
||||
virtual bool setData(const QModelIndex &index, const QVariant &value,
|
||||
int role = Qt::EditRole)
|
||||
virtual bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole)
|
||||
{
|
||||
auto model = sourceModel();
|
||||
if (!model)
|
||||
@ -189,23 +180,21 @@ public:
|
||||
// FIXME: this is a workaround for a bug in QFileSystemModel, where it doesn't
|
||||
// sort after renames
|
||||
{
|
||||
((QFileSystemModel *)model)->setNameFilterDisables(true);
|
||||
((QFileSystemModel *)model)->setNameFilterDisables(false);
|
||||
((QFileSystemModel*)model)->setNameFilterDisables(true);
|
||||
((QFileSystemModel*)model)->setNameFilterDisables(false);
|
||||
}
|
||||
return model->setData(mapToSource(index), value.toString() + ".png", role);
|
||||
}
|
||||
|
||||
private:
|
||||
private:
|
||||
void thumbnailImage(QString path)
|
||||
{
|
||||
auto runnable = new ThumbnailRunnable(path, m_thumbnailCache);
|
||||
connect(&(runnable->m_resultEmitter), SIGNAL(resultsReady(QString)),
|
||||
SLOT(thumbnailReady(QString)));
|
||||
connect(&(runnable->m_resultEmitter), SIGNAL(resultsFailed(QString)),
|
||||
SLOT(thumbnailFailed(QString)));
|
||||
((QThreadPool &)m_thumbnailingPool).start(runnable);
|
||||
connect(&(runnable->m_resultEmitter), SIGNAL(resultsReady(QString)), SLOT(thumbnailReady(QString)));
|
||||
connect(&(runnable->m_resultEmitter), SIGNAL(resultsFailed(QString)), SLOT(thumbnailFailed(QString)));
|
||||
((QThreadPool&)m_thumbnailingPool).start(runnable);
|
||||
}
|
||||
private slots:
|
||||
private slots:
|
||||
void thumbnailReady(QString path) { emit layoutChanged(); }
|
||||
void thumbnailFailed(QString path) { m_failed.insert(path); }
|
||||
void fileChanged(QString filepath)
|
||||
@ -219,7 +208,7 @@ private slots:
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
private:
|
||||
SharedIconCachePtr m_thumbnailCache;
|
||||
QThreadPool m_thumbnailingPool;
|
||||
QSet<QString> m_failed;
|
||||
@ -227,18 +216,15 @@ private:
|
||||
QFileSystemWatcher watcher;
|
||||
};
|
||||
|
||||
class CenteredEditingDelegate : public QStyledItemDelegate
|
||||
{
|
||||
public:
|
||||
explicit CenteredEditingDelegate(QObject *parent = 0) : QStyledItemDelegate(parent) {}
|
||||
class CenteredEditingDelegate : public QStyledItemDelegate {
|
||||
public:
|
||||
explicit CenteredEditingDelegate(QObject* parent = 0) : QStyledItemDelegate(parent) {}
|
||||
virtual ~CenteredEditingDelegate() {}
|
||||
virtual QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const
|
||||
virtual QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const
|
||||
{
|
||||
auto widget = QStyledItemDelegate::createEditor(parent, option, index);
|
||||
auto foo = dynamic_cast<QLineEdit *>(widget);
|
||||
if (foo)
|
||||
{
|
||||
auto foo = dynamic_cast<QLineEdit*>(widget);
|
||||
if (foo) {
|
||||
foo->setAlignment(Qt::AlignHCenter);
|
||||
foo->setFrame(true);
|
||||
foo->setMaximumWidth(192);
|
||||
@ -247,15 +233,14 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
ScreenshotsPage::ScreenshotsPage(QString path, QWidget *parent)
|
||||
: QMainWindow(parent), ui(new Ui::ScreenshotsPage)
|
||||
ScreenshotsPage::ScreenshotsPage(QString path, QWidget* parent) : QMainWindow(parent), ui(new Ui::ScreenshotsPage)
|
||||
{
|
||||
m_model.reset(new QFileSystemModel());
|
||||
m_filterModel.reset(new FilterModel());
|
||||
m_filterModel->setSourceModel(m_model.get());
|
||||
m_model->setFilter(QDir::Files);
|
||||
m_model->setReadOnly(false);
|
||||
m_model->setNameFilters({"*.png"});
|
||||
m_model->setNameFilters({ "*.png" });
|
||||
m_model->setNameFilterDisables(false);
|
||||
m_folder = path;
|
||||
m_valid = FS::ensureFolderPathExists(m_folder);
|
||||
@ -278,31 +263,29 @@ ScreenshotsPage::ScreenshotsPage(QString path, QWidget *parent)
|
||||
connect(ui->listView, SIGNAL(activated(QModelIndex)), SLOT(onItemActivated(QModelIndex)));
|
||||
}
|
||||
|
||||
bool ScreenshotsPage::eventFilter(QObject *obj, QEvent *evt)
|
||||
bool ScreenshotsPage::eventFilter(QObject* obj, QEvent* evt)
|
||||
{
|
||||
if (obj != ui->listView)
|
||||
return QWidget::eventFilter(obj, evt);
|
||||
if (evt->type() != QEvent::KeyPress)
|
||||
{
|
||||
if (evt->type() != QEvent::KeyPress) {
|
||||
return QWidget::eventFilter(obj, evt);
|
||||
}
|
||||
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(evt);
|
||||
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(evt);
|
||||
|
||||
if (keyEvent->matches(QKeySequence::Copy)) {
|
||||
on_actionCopy_File_s_triggered();
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (keyEvent->key())
|
||||
{
|
||||
case Qt::Key_Delete:
|
||||
on_actionDelete_triggered();
|
||||
return true;
|
||||
case Qt::Key_F2:
|
||||
on_actionRename_triggered();
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
switch (keyEvent->key()) {
|
||||
case Qt::Key_Delete:
|
||||
on_actionDelete_triggered();
|
||||
return true;
|
||||
case Qt::Key_F2:
|
||||
on_actionRename_triggered();
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return QWidget::eventFilter(obj, evt);
|
||||
}
|
||||
@ -322,17 +305,17 @@ void ScreenshotsPage::ShowContextMenu(const QPoint& pos)
|
||||
auto menu = ui->toolBar->createContextMenu(this, tr("Context menu"));
|
||||
|
||||
if (ui->listView->selectionModel()->selectedRows().size() > 1) {
|
||||
menu->removeAction( ui->actionCopy_Image );
|
||||
menu->removeAction(ui->actionCopy_Image);
|
||||
}
|
||||
|
||||
menu->exec(ui->listView->mapToGlobal(pos));
|
||||
delete menu;
|
||||
}
|
||||
|
||||
QMenu * ScreenshotsPage::createPopupMenu()
|
||||
QMenu* ScreenshotsPage::createPopupMenu()
|
||||
{
|
||||
QMenu* filteredMenu = QMainWindow::createPopupMenu();
|
||||
filteredMenu->removeAction( ui->toolBar->toggleViewAction() );
|
||||
filteredMenu->removeAction(ui->toolBar->toggleViewAction());
|
||||
return filteredMenu;
|
||||
}
|
||||
|
||||
@ -345,13 +328,12 @@ void ScreenshotsPage::onItemActivated(QModelIndex index)
|
||||
DesktopServices::openFile(info.absoluteFilePath());
|
||||
}
|
||||
|
||||
void ScreenshotsPage::onCurrentSelectionChanged(const QItemSelection &selected)
|
||||
void ScreenshotsPage::onCurrentSelectionChanged(const QItemSelection& selected)
|
||||
{
|
||||
bool allReadable = !selected.isEmpty();
|
||||
bool allWritable = !selected.isEmpty();
|
||||
|
||||
for (auto index : selected.indexes())
|
||||
{
|
||||
for (auto index : selected.indexes()) {
|
||||
if (!index.isValid())
|
||||
break;
|
||||
auto info = m_model->fileInfo(index);
|
||||
@ -401,8 +383,7 @@ void ScreenshotsPage::on_actionUpload_triggered()
|
||||
|
||||
QList<ScreenShot::Ptr> uploaded;
|
||||
auto job = NetJob::Ptr(new NetJob("Screenshot Upload", APPLICATION->network()));
|
||||
if(selection.size() < 2)
|
||||
{
|
||||
if (selection.size() < 2) {
|
||||
auto item = selection.at(0);
|
||||
auto info = m_model->fileInfo(item);
|
||||
auto screenshot = std::make_shared<ScreenShot>(info);
|
||||
@ -411,31 +392,24 @@ void ScreenshotsPage::on_actionUpload_triggered()
|
||||
m_uploadActive = true;
|
||||
ProgressDialog dialog(this);
|
||||
|
||||
if(dialog.execWithTask(job.get()) != QDialog::Accepted)
|
||||
{
|
||||
CustomMessageBox::selectable(this, tr("Failed to upload screenshots!"),
|
||||
tr("Unknown error"), QMessageBox::Warning)->exec();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dialog.execWithTask(job.get()) != QDialog::Accepted) {
|
||||
CustomMessageBox::selectable(this, tr("Failed to upload screenshots!"), tr("Unknown error"), QMessageBox::Warning)->exec();
|
||||
} else {
|
||||
auto link = screenshot->m_url;
|
||||
QClipboard *clipboard = QApplication::clipboard();
|
||||
QClipboard* clipboard = QApplication::clipboard();
|
||||
clipboard->setText(link);
|
||||
CustomMessageBox::selectable(
|
||||
this,
|
||||
tr("Upload finished"),
|
||||
tr("The <a href=\"%1\">link to the uploaded screenshot</a> has been placed in your clipboard.")
|
||||
.arg(link),
|
||||
QMessageBox::Information
|
||||
)->exec();
|
||||
this, tr("Upload finished"),
|
||||
tr("The <a href=\"%1\">link to the uploaded screenshot</a> has been placed in your clipboard.").arg(link),
|
||||
QMessageBox::Information)
|
||||
->exec();
|
||||
}
|
||||
|
||||
m_uploadActive = false;
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto item : selection)
|
||||
{
|
||||
for (auto item : selection) {
|
||||
auto info = m_model->fileInfo(item);
|
||||
auto screenshot = std::make_shared<ScreenShot>(info);
|
||||
uploaded.push_back(screenshot);
|
||||
@ -449,26 +423,16 @@ void ScreenshotsPage::on_actionUpload_triggered()
|
||||
task.addTask(albumTask);
|
||||
m_uploadActive = true;
|
||||
ProgressDialog prog(this);
|
||||
if (prog.execWithTask(&task) != QDialog::Accepted)
|
||||
{
|
||||
CustomMessageBox::selectable(
|
||||
this,
|
||||
tr("Failed to upload screenshots!"),
|
||||
tr("Unknown error"),
|
||||
QMessageBox::Warning
|
||||
)->exec();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (prog.execWithTask(&task) != QDialog::Accepted) {
|
||||
CustomMessageBox::selectable(this, tr("Failed to upload screenshots!"), tr("Unknown error"), QMessageBox::Warning)->exec();
|
||||
} else {
|
||||
auto link = QString("https://imgur.com/a/%1").arg(imgurAlbum->id());
|
||||
QClipboard *clipboard = QApplication::clipboard();
|
||||
QClipboard* clipboard = QApplication::clipboard();
|
||||
clipboard->setText(link);
|
||||
CustomMessageBox::selectable(
|
||||
this,
|
||||
tr("Upload finished"),
|
||||
tr("The <a href=\"%1\">link to the uploaded album</a> has been placed in your clipboard.") .arg(link),
|
||||
QMessageBox::Information
|
||||
)->exec();
|
||||
CustomMessageBox::selectable(this, tr("Upload finished"),
|
||||
tr("The <a href=\"%1\">link to the uploaded album</a> has been placed in your clipboard.").arg(link),
|
||||
QMessageBox::Information)
|
||||
->exec();
|
||||
}
|
||||
m_uploadActive = false;
|
||||
}
|
||||
@ -476,8 +440,7 @@ void ScreenshotsPage::on_actionUpload_triggered()
|
||||
void ScreenshotsPage::on_actionCopy_Image_triggered()
|
||||
{
|
||||
auto selection = ui->listView->selectionModel()->selectedRows();
|
||||
if(selection.size() < 1)
|
||||
{
|
||||
if (selection.size() < 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -492,15 +455,13 @@ void ScreenshotsPage::on_actionCopy_Image_triggered()
|
||||
void ScreenshotsPage::on_actionCopy_File_s_triggered()
|
||||
{
|
||||
auto selection = ui->listView->selectionModel()->selectedRows();
|
||||
if(selection.size() < 1)
|
||||
{
|
||||
if (selection.size() < 1) {
|
||||
// Don't do anything so we don't empty the users clipboard
|
||||
return;
|
||||
}
|
||||
|
||||
QString buf = "";
|
||||
for (auto item : selection)
|
||||
{
|
||||
for (auto item : selection) {
|
||||
auto info = m_model->fileInfo(item);
|
||||
buf += "file:///" + info.absoluteFilePath() + "\r\n";
|
||||
}
|
||||
@ -532,8 +493,7 @@ void ScreenshotsPage::on_actionDelete_triggered()
|
||||
if (response != QMessageBox::Yes)
|
||||
return;
|
||||
|
||||
for (auto item : selected)
|
||||
{
|
||||
for (auto item : selected) {
|
||||
if (FS::trash(m_model->filePath(item)))
|
||||
continue;
|
||||
|
||||
@ -552,23 +512,19 @@ void ScreenshotsPage::on_actionRename_triggered()
|
||||
|
||||
void ScreenshotsPage::openedImpl()
|
||||
{
|
||||
if(!m_valid)
|
||||
{
|
||||
if (!m_valid) {
|
||||
m_valid = FS::ensureFolderPathExists(m_folder);
|
||||
}
|
||||
if (m_valid)
|
||||
{
|
||||
if (m_valid) {
|
||||
QString path = QDir(m_folder).absolutePath();
|
||||
auto idx = m_model->setRootPath(path);
|
||||
if(idx.isValid())
|
||||
{
|
||||
if (idx.isValid()) {
|
||||
ui->listView->setModel(m_filterModel.get());
|
||||
connect(ui->listView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &ScreenshotsPage::onCurrentSelectionChanged);
|
||||
onCurrentSelectionChanged(ui->listView->selectionModel()->selection()); // set initial button enable states
|
||||
connect(ui->listView->selectionModel(), &QItemSelectionModel::selectionChanged, this,
|
||||
&ScreenshotsPage::onCurrentSelectionChanged);
|
||||
onCurrentSelectionChanged(ui->listView->selectionModel()->selection()); // set initial button enable states
|
||||
ui->listView->setRootIndex(m_filterModel->mapFromSource(idx));
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ui->listView->setModel(nullptr);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
/*
|
||||
* PolyMC - Minecraft Launcher
|
||||
* Prism Launcher - Minecraft Launcher
|
||||
* Copyright (c) 2022 Jamie Mansfield <jmansfield@cadixdev.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
@ -37,16 +37,15 @@
|
||||
|
||||
#include <QMainWindow>
|
||||
|
||||
#include "ui/pages/BasePage.h"
|
||||
#include <Application.h>
|
||||
#include "ui/pages/BasePage.h"
|
||||
|
||||
#include "settings/Setting.h"
|
||||
|
||||
class QFileSystemModel;
|
||||
class QIdentityProxyModel;
|
||||
class QItemSelection;
|
||||
namespace Ui
|
||||
{
|
||||
namespace Ui {
|
||||
class ScreenshotsPage;
|
||||
}
|
||||
|
||||
@ -54,49 +53,30 @@ struct ScreenShot;
|
||||
class ScreenshotList;
|
||||
class ImgurAlbumCreation;
|
||||
|
||||
class ScreenshotsPage : public QMainWindow, public BasePage
|
||||
{
|
||||
class ScreenshotsPage : public QMainWindow, public BasePage {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ScreenshotsPage(QString path, QWidget *parent = 0);
|
||||
public:
|
||||
explicit ScreenshotsPage(QString path, QWidget* parent = 0);
|
||||
virtual ~ScreenshotsPage();
|
||||
|
||||
void openedImpl() override;
|
||||
void closedImpl() override;
|
||||
|
||||
enum
|
||||
{
|
||||
NothingDone = 0x42
|
||||
};
|
||||
enum { NothingDone = 0x42 };
|
||||
|
||||
virtual bool eventFilter(QObject *, QEvent *) override;
|
||||
virtual QString displayName() const override
|
||||
{
|
||||
return tr("Screenshots");
|
||||
}
|
||||
virtual QIcon icon() const override
|
||||
{
|
||||
return APPLICATION->getThemedIcon("screenshots");
|
||||
}
|
||||
virtual QString id() const override
|
||||
{
|
||||
return "screenshots";
|
||||
}
|
||||
virtual QString helpPage() const override
|
||||
{
|
||||
return "Screenshots-management";
|
||||
}
|
||||
virtual bool apply() override
|
||||
{
|
||||
return !m_uploadActive;
|
||||
}
|
||||
virtual bool eventFilter(QObject*, QEvent*) override;
|
||||
virtual QString displayName() const override { return tr("Screenshots"); }
|
||||
virtual QIcon icon() const override { return APPLICATION->getThemedIcon("screenshots"); }
|
||||
virtual QString id() const override { return "screenshots"; }
|
||||
virtual QString helpPage() const override { return "Screenshots-management"; }
|
||||
virtual bool apply() override { return !m_uploadActive; }
|
||||
void retranslate() override;
|
||||
|
||||
protected:
|
||||
QMenu * createPopupMenu() override;
|
||||
protected:
|
||||
QMenu* createPopupMenu() override;
|
||||
|
||||
private slots:
|
||||
private slots:
|
||||
void on_actionUpload_triggered();
|
||||
void on_actionCopy_Image_triggered();
|
||||
void on_actionCopy_File_s_triggered();
|
||||
@ -104,11 +84,11 @@ private slots:
|
||||
void on_actionRename_triggered();
|
||||
void on_actionView_Folder_triggered();
|
||||
void onItemActivated(QModelIndex);
|
||||
void onCurrentSelectionChanged(const QItemSelection &selected);
|
||||
void ShowContextMenu(const QPoint &pos);
|
||||
void onCurrentSelectionChanged(const QItemSelection& selected);
|
||||
void ShowContextMenu(const QPoint& pos);
|
||||
|
||||
private:
|
||||
Ui::ScreenshotsPage *ui;
|
||||
private:
|
||||
Ui::ScreenshotsPage* ui;
|
||||
std::shared_ptr<QFileSystemModel> m_model;
|
||||
std::shared_ptr<QIdentityProxyModel> m_filterModel;
|
||||
QString m_folder;
|
||||
|
@ -40,36 +40,27 @@
|
||||
#include "ui_ServersPage.h"
|
||||
|
||||
#include <FileSystem.h>
|
||||
#include <sstream>
|
||||
#include <io/stream_reader.h>
|
||||
#include <tag_string.h>
|
||||
#include <tag_primitive.h>
|
||||
#include <tag_list.h>
|
||||
#include <tag_compound.h>
|
||||
#include <minecraft/MinecraftInstance.h>
|
||||
#include <tag_compound.h>
|
||||
#include <tag_list.h>
|
||||
#include <tag_primitive.h>
|
||||
#include <tag_string.h>
|
||||
#include <sstream>
|
||||
|
||||
#include <QFileSystemWatcher>
|
||||
#include <QMenu>
|
||||
#include <QTimer>
|
||||
|
||||
static const int COLUMN_COUNT = 2; // 3 , TBD: latency and other nice things.
|
||||
static const int COLUMN_COUNT = 2; // 3 , TBD: latency and other nice things.
|
||||
|
||||
struct Server
|
||||
{
|
||||
struct Server {
|
||||
// Types
|
||||
enum class AcceptsTextures : int
|
||||
{
|
||||
ASK = 0,
|
||||
ALWAYS = 1,
|
||||
NEVER = 2
|
||||
};
|
||||
enum class AcceptsTextures : int { ASK = 0, ALWAYS = 1, NEVER = 2 };
|
||||
|
||||
// Methods
|
||||
Server()
|
||||
{
|
||||
m_name = QObject::tr("Minecraft Server");
|
||||
}
|
||||
Server(const QString & name, const QString & address)
|
||||
Server() { m_name = QObject::tr("Minecraft Server"); }
|
||||
Server(const QString& name, const QString& address)
|
||||
{
|
||||
m_name = name;
|
||||
m_address = address;
|
||||
@ -82,21 +73,16 @@ struct Server
|
||||
std::string nameStr(server["name"]);
|
||||
m_name = QString::fromUtf8(nameStr.c_str());
|
||||
|
||||
if(server["icon"])
|
||||
{
|
||||
if (server["icon"]) {
|
||||
std::string base64str(server["icon"]);
|
||||
m_icon = QByteArray::fromBase64(base64str.c_str());
|
||||
}
|
||||
|
||||
if(server.has_key("acceptTextures", nbt::tag_type::Byte))
|
||||
{
|
||||
if (server.has_key("acceptTextures", nbt::tag_type::Byte)) {
|
||||
bool value = server["acceptTextures"].as<nbt::tag_byte>().get();
|
||||
if(value)
|
||||
{
|
||||
if (value) {
|
||||
m_acceptsTextures = AcceptsTextures::ALWAYS;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
m_acceptsTextures = AcceptsTextures::NEVER;
|
||||
}
|
||||
}
|
||||
@ -106,12 +92,10 @@ struct Server
|
||||
{
|
||||
server.insert("name", m_name.trimmed().toUtf8().toStdString());
|
||||
server.insert("ip", m_address.trimmed().toUtf8().toStdString());
|
||||
if(m_icon.size())
|
||||
{
|
||||
if (m_icon.size()) {
|
||||
server.insert("icon", m_icon.toBase64().toStdString());
|
||||
}
|
||||
if(m_acceptsTextures != AcceptsTextures::ASK)
|
||||
{
|
||||
if (m_acceptsTextures != AcceptsTextures::ASK) {
|
||||
server.insert("acceptTextures", nbt::tag_byte(m_acceptsTextures == AcceptsTextures::ALWAYS));
|
||||
}
|
||||
}
|
||||
@ -127,64 +111,54 @@ struct Server
|
||||
// Data - temporary
|
||||
bool m_checked = false;
|
||||
bool m_up = false;
|
||||
QString m_motd; // https://mctools.org/motd-creator
|
||||
QString m_motd; // https://mctools.org/motd-creator
|
||||
int m_ping = 0;
|
||||
int m_currentPlayers = 0;
|
||||
int m_maxPlayers = 0;
|
||||
};
|
||||
|
||||
static std::unique_ptr <nbt::tag_compound> parseServersDat(const QString& filename)
|
||||
static std::unique_ptr<nbt::tag_compound> parseServersDat(const QString& filename)
|
||||
{
|
||||
try
|
||||
{
|
||||
try {
|
||||
QByteArray input = FS::read(filename);
|
||||
std::istringstream foo(std::string(input.constData(), input.size()));
|
||||
auto pair = nbt::io::read_compound(foo);
|
||||
|
||||
if(pair.first != "")
|
||||
if (pair.first != "")
|
||||
return nullptr;
|
||||
|
||||
if(pair.second == nullptr)
|
||||
if (pair.second == nullptr)
|
||||
return nullptr;
|
||||
|
||||
return std::move(pair.second);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
} catch (...) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
static bool serializeServerDat(const QString& filename, nbt::tag_compound * levelInfo)
|
||||
static bool serializeServerDat(const QString& filename, nbt::tag_compound* levelInfo)
|
||||
{
|
||||
try
|
||||
{
|
||||
if(!FS::ensureFilePathExists(filename))
|
||||
{
|
||||
try {
|
||||
if (!FS::ensureFilePathExists(filename)) {
|
||||
return false;
|
||||
}
|
||||
std::ostringstream s;
|
||||
nbt::io::write_tag("", *levelInfo, s);
|
||||
QByteArray val(s.str().data(), (int) s.str().size() );
|
||||
QByteArray val(s.str().data(), (int)s.str().size());
|
||||
FS::write(filename, val);
|
||||
return true;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
} catch (...) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
class ServersModel: public QAbstractListModel
|
||||
{
|
||||
class ServersModel : public QAbstractListModel {
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum Roles
|
||||
{
|
||||
public:
|
||||
enum Roles {
|
||||
ServerPtrRole = Qt::UserRole,
|
||||
};
|
||||
explicit ServersModel(const QString &path, QObject *parent = 0)
|
||||
: QAbstractListModel(parent)
|
||||
explicit ServersModel(const QString& path, QObject* parent = 0) : QAbstractListModel(parent)
|
||||
{
|
||||
m_path = path;
|
||||
m_watcher = new QFileSystemWatcher(this);
|
||||
@ -194,18 +168,16 @@ public:
|
||||
m_saveTimer.setInterval(5000);
|
||||
connect(&m_saveTimer, &QTimer::timeout, this, &ServersModel::save_internal);
|
||||
}
|
||||
virtual ~ServersModel() {};
|
||||
virtual ~ServersModel(){};
|
||||
|
||||
void observe()
|
||||
{
|
||||
if(m_observed)
|
||||
{
|
||||
if (m_observed) {
|
||||
return;
|
||||
}
|
||||
m_observed = true;
|
||||
|
||||
if(!m_loaded)
|
||||
{
|
||||
if (!m_loaded) {
|
||||
load();
|
||||
}
|
||||
|
||||
@ -214,8 +186,7 @@ public:
|
||||
|
||||
void unobserve()
|
||||
{
|
||||
if(!m_observed)
|
||||
{
|
||||
if (!m_observed) {
|
||||
return;
|
||||
}
|
||||
m_observed = false;
|
||||
@ -225,8 +196,7 @@ public:
|
||||
|
||||
void lock()
|
||||
{
|
||||
if(m_locked)
|
||||
{
|
||||
if (m_locked) {
|
||||
return;
|
||||
}
|
||||
saveNow();
|
||||
@ -237,8 +207,7 @@ public:
|
||||
|
||||
void unlock()
|
||||
{
|
||||
if(!m_locked)
|
||||
{
|
||||
if (!m_locked) {
|
||||
return;
|
||||
}
|
||||
m_locked = false;
|
||||
@ -248,12 +217,10 @@ public:
|
||||
|
||||
int addEmptyRow(int position)
|
||||
{
|
||||
if(m_locked)
|
||||
{
|
||||
if (m_locked) {
|
||||
return -1;
|
||||
}
|
||||
if(position < 0 || position >= rowCount())
|
||||
{
|
||||
if (position < 0 || position >= rowCount()) {
|
||||
position = rowCount();
|
||||
}
|
||||
beginInsertRows(QModelIndex(), position, position);
|
||||
@ -265,36 +232,32 @@ public:
|
||||
|
||||
bool removeRow(int row)
|
||||
{
|
||||
if(m_locked)
|
||||
{
|
||||
if (m_locked) {
|
||||
return false;
|
||||
}
|
||||
if(row < 0 || row >= rowCount())
|
||||
{
|
||||
if (row < 0 || row >= rowCount()) {
|
||||
return false;
|
||||
}
|
||||
beginRemoveRows(QModelIndex(), row, row);
|
||||
m_servers.removeAt(row);
|
||||
endRemoveRows(); // does absolutely nothing, the selected server stays as the next line...
|
||||
endRemoveRows(); // does absolutely nothing, the selected server stays as the next line...
|
||||
scheduleSave();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool moveUp(int row)
|
||||
{
|
||||
if(m_locked)
|
||||
{
|
||||
if (m_locked) {
|
||||
return false;
|
||||
}
|
||||
if(row <= 0)
|
||||
{
|
||||
if (row <= 0) {
|
||||
return false;
|
||||
}
|
||||
beginMoveRows(QModelIndex(), row, row, QModelIndex(), row - 1);
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0)
|
||||
m_servers.swapItemsAt(row-1, row);
|
||||
m_servers.swapItemsAt(row - 1, row);
|
||||
#else
|
||||
m_servers.swap(row-1, row);
|
||||
m_servers.swap(row - 1, row);
|
||||
#endif
|
||||
endMoveRows();
|
||||
scheduleSave();
|
||||
@ -303,20 +266,18 @@ public:
|
||||
|
||||
bool moveDown(int row)
|
||||
{
|
||||
if(m_locked)
|
||||
{
|
||||
if (m_locked) {
|
||||
return false;
|
||||
}
|
||||
int count = rowCount();
|
||||
if(row + 1 >= count)
|
||||
{
|
||||
if (row + 1 >= count) {
|
||||
return false;
|
||||
}
|
||||
beginMoveRows(QModelIndex(), row, row, QModelIndex(), row + 2);
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0)
|
||||
m_servers.swapItemsAt(row+1, row);
|
||||
m_servers.swapItemsAt(row + 1, row);
|
||||
#else
|
||||
m_servers.swap(row+1, row);
|
||||
m_servers.swap(row + 1, row);
|
||||
#endif
|
||||
endMoveRows();
|
||||
scheduleSave();
|
||||
@ -328,10 +289,8 @@ public:
|
||||
if (section < 0 || section >= COLUMN_COUNT)
|
||||
return QVariant();
|
||||
|
||||
if(role == Qt::DisplayRole)
|
||||
{
|
||||
switch(section)
|
||||
{
|
||||
if (role == Qt::DisplayRole) {
|
||||
switch (section) {
|
||||
case 0:
|
||||
return tr("Name");
|
||||
case 1:
|
||||
@ -344,90 +303,81 @@ public:
|
||||
return QAbstractListModel::headerData(section, orientation, role);
|
||||
}
|
||||
|
||||
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override
|
||||
virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override
|
||||
{
|
||||
if (!index.isValid())
|
||||
return QVariant();
|
||||
|
||||
int row = index.row();
|
||||
int column = index.column();
|
||||
if(column < 0 || column >= COLUMN_COUNT)
|
||||
if (column < 0 || column >= COLUMN_COUNT)
|
||||
return QVariant();
|
||||
|
||||
if (row < 0 || row >= m_servers.size())
|
||||
return QVariant();
|
||||
|
||||
switch(column)
|
||||
{
|
||||
switch (column) {
|
||||
case 0:
|
||||
switch (role)
|
||||
{
|
||||
case Qt::DecorationRole:
|
||||
{
|
||||
auto & bytes = m_servers[row].m_icon;
|
||||
if(bytes.size())
|
||||
{
|
||||
QPixmap px;
|
||||
if(px.loadFromData(bytes))
|
||||
return QIcon(px);
|
||||
switch (role) {
|
||||
case Qt::DecorationRole: {
|
||||
auto& bytes = m_servers[row].m_icon;
|
||||
if (bytes.size()) {
|
||||
QPixmap px;
|
||||
if (px.loadFromData(bytes))
|
||||
return QIcon(px);
|
||||
}
|
||||
return APPLICATION->getThemedIcon("unknown_server");
|
||||
}
|
||||
return APPLICATION->getThemedIcon("unknown_server");
|
||||
}
|
||||
case Qt::DisplayRole:
|
||||
return m_servers[row].m_name;
|
||||
case ServerPtrRole:
|
||||
return QVariant::fromValue<void *>((void *)&m_servers[row]);
|
||||
default:
|
||||
return QVariant();
|
||||
case Qt::DisplayRole:
|
||||
return m_servers[row].m_name;
|
||||
case ServerPtrRole:
|
||||
return QVariant::fromValue<void*>((void*)&m_servers[row]);
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
case 1:
|
||||
switch (role)
|
||||
{
|
||||
case Qt::DisplayRole:
|
||||
return m_servers[row].m_address;
|
||||
default:
|
||||
return QVariant();
|
||||
switch (role) {
|
||||
case Qt::DisplayRole:
|
||||
return m_servers[row].m_address;
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
case 2:
|
||||
switch (role)
|
||||
{
|
||||
case Qt::DisplayRole:
|
||||
return m_servers[row].m_ping;
|
||||
default:
|
||||
return QVariant();
|
||||
switch (role) {
|
||||
case Qt::DisplayRole:
|
||||
return m_servers[row].m_ping;
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
|
||||
virtual int rowCount(const QModelIndex &parent = QModelIndex()) const override
|
||||
virtual int rowCount(const QModelIndex& parent = QModelIndex()) const override
|
||||
{
|
||||
return parent.isValid() ? 0 : m_servers.size();
|
||||
}
|
||||
int columnCount(const QModelIndex & parent) const override
|
||||
int columnCount(const QModelIndex& parent) const override
|
||||
{
|
||||
return parent.isValid() ? 0 : COLUMN_COUNT;
|
||||
}
|
||||
|
||||
Server * at(int index)
|
||||
Server* at(int index)
|
||||
{
|
||||
if(index < 0 || index >= rowCount())
|
||||
{
|
||||
if (index < 0 || index >= rowCount()) {
|
||||
return nullptr;
|
||||
}
|
||||
return &m_servers[index];
|
||||
}
|
||||
|
||||
void setName(int row, const QString & name)
|
||||
void setName(int row, const QString& name)
|
||||
{
|
||||
if(m_locked)
|
||||
{
|
||||
if (m_locked) {
|
||||
return;
|
||||
}
|
||||
auto server = at(row);
|
||||
if(!server || server->m_name == name)
|
||||
{
|
||||
if (!server || server->m_name == name) {
|
||||
return;
|
||||
}
|
||||
server->m_name = name;
|
||||
@ -435,15 +385,13 @@ public:
|
||||
scheduleSave();
|
||||
}
|
||||
|
||||
void setAddress(int row, const QString & address)
|
||||
void setAddress(int row, const QString& address)
|
||||
{
|
||||
if(m_locked)
|
||||
{
|
||||
if (m_locked) {
|
||||
return;
|
||||
}
|
||||
auto server = at(row);
|
||||
if(!server || server->m_address == address)
|
||||
{
|
||||
if (!server || server->m_address == address) {
|
||||
return;
|
||||
}
|
||||
server->m_address = address;
|
||||
@ -453,13 +401,11 @@ public:
|
||||
|
||||
void setAcceptsTextures(int row, Server::AcceptsTextures textures)
|
||||
{
|
||||
if(m_locked)
|
||||
{
|
||||
if (m_locked) {
|
||||
return;
|
||||
}
|
||||
auto server = at(row);
|
||||
if(!server || server->m_acceptsTextures == textures)
|
||||
{
|
||||
if (!server || server->m_acceptsTextures == textures) {
|
||||
return;
|
||||
}
|
||||
server->m_acceptsTextures = textures;
|
||||
@ -473,12 +419,10 @@ public:
|
||||
beginResetModel();
|
||||
QList<Server> servers;
|
||||
auto serversDat = parseServersDat(serversPath());
|
||||
if(serversDat)
|
||||
{
|
||||
auto &serversList = serversDat->at("servers").as<nbt::tag_list>();
|
||||
for(auto iter = serversList.begin(); iter != serversList.end(); iter++)
|
||||
{
|
||||
auto & serverTag = (*iter).as<nbt::tag_compound>();
|
||||
if (serversDat) {
|
||||
auto& serversList = serversDat->at("servers").as<nbt::tag_list>();
|
||||
for (auto iter = serversList.begin(); iter != serversList.end(); iter++) {
|
||||
auto& serverTag = (*iter).as<nbt::tag_compound>();
|
||||
Server s(serverTag);
|
||||
servers.append(s);
|
||||
}
|
||||
@ -490,14 +434,12 @@ public:
|
||||
|
||||
void saveNow()
|
||||
{
|
||||
if(saveIsScheduled())
|
||||
{
|
||||
if (saveIsScheduled()) {
|
||||
save_internal();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public slots:
|
||||
public slots:
|
||||
void dirChanged(const QString& path)
|
||||
{
|
||||
qDebug() << "Changed:" << path;
|
||||
@ -508,7 +450,7 @@ public slots:
|
||||
qDebug() << "Changed:" << path;
|
||||
}
|
||||
|
||||
private slots:
|
||||
private slots:
|
||||
void save_internal()
|
||||
{
|
||||
cancelSave();
|
||||
@ -517,31 +459,27 @@ private slots:
|
||||
|
||||
nbt::tag_compound out;
|
||||
nbt::tag_list list;
|
||||
for(auto & server: m_servers)
|
||||
{
|
||||
for (auto& server : m_servers) {
|
||||
nbt::tag_compound serverNbt;
|
||||
server.serialize(serverNbt);
|
||||
list.push_back(std::move(serverNbt));
|
||||
}
|
||||
out.insert("servers", nbt::value(std::move(list)));
|
||||
|
||||
if(!serializeServerDat(path, &out))
|
||||
{
|
||||
if (!serializeServerDat(path, &out)) {
|
||||
qDebug() << "Failed to save server list:" << path << "Will try again.";
|
||||
scheduleSave();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
private:
|
||||
void scheduleSave()
|
||||
{
|
||||
if(!m_loaded)
|
||||
{
|
||||
if (!m_loaded) {
|
||||
qDebug() << "Server list should never save if it didn't successfully load, path:" << m_path;
|
||||
return;
|
||||
}
|
||||
if(!m_dirty)
|
||||
{
|
||||
if (!m_dirty) {
|
||||
m_dirty = true;
|
||||
qDebug() << "Server list save is scheduled for" << m_path;
|
||||
}
|
||||
@ -562,24 +500,17 @@ private:
|
||||
void updateFSObserver()
|
||||
{
|
||||
bool observingFS = m_watcher->directories().contains(m_path);
|
||||
if(m_observed && m_locked)
|
||||
{
|
||||
if(!observingFS)
|
||||
{
|
||||
if (m_observed && m_locked) {
|
||||
if (!observingFS) {
|
||||
qWarning() << "Will watch" << m_path;
|
||||
if(!m_watcher->addPath(m_path))
|
||||
{
|
||||
if (!m_watcher->addPath(m_path)) {
|
||||
qWarning() << "Failed to start watching" << m_path;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(observingFS)
|
||||
{
|
||||
} else {
|
||||
if (observingFS) {
|
||||
qWarning() << "Will stop watching" << m_path;
|
||||
if(!m_watcher->removePath(m_path))
|
||||
{
|
||||
if (!m_watcher->removePath(m_path)) {
|
||||
qWarning() << "Failed to stop watching" << m_path;
|
||||
}
|
||||
}
|
||||
@ -592,34 +523,31 @@ private:
|
||||
return foo.filePath();
|
||||
}
|
||||
|
||||
private:
|
||||
private:
|
||||
bool m_loaded = false;
|
||||
bool m_locked = false;
|
||||
bool m_observed = false;
|
||||
bool m_dirty = false;
|
||||
QString m_path;
|
||||
QList<Server> m_servers;
|
||||
QFileSystemWatcher *m_watcher = nullptr;
|
||||
QFileSystemWatcher* m_watcher = nullptr;
|
||||
QTimer m_saveTimer;
|
||||
};
|
||||
|
||||
ServersPage::ServersPage(InstancePtr inst, QWidget* parent)
|
||||
: QMainWindow(parent), ui(new Ui::ServersPage)
|
||||
ServersPage::ServersPage(InstancePtr inst, QWidget* parent) : QMainWindow(parent), ui(new Ui::ServersPage)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
m_inst = inst;
|
||||
m_model = new ServersModel(inst->gameRoot(), this);
|
||||
ui->serversView->setIconSize(QSize(64,64));
|
||||
ui->serversView->setIconSize(QSize(64, 64));
|
||||
ui->serversView->setModel(m_model);
|
||||
ui->serversView->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
connect(ui->serversView, &QTreeView::customContextMenuRequested, this, &ServersPage::ShowContextMenu);
|
||||
|
||||
auto head = ui->serversView->header();
|
||||
if(head->count())
|
||||
{
|
||||
if (head->count()) {
|
||||
head->setSectionResizeMode(0, QHeaderView::Stretch);
|
||||
for(int i = 1; i < head->count(); i++)
|
||||
{
|
||||
for (int i = 1; i < head->count(); i++) {
|
||||
head->setSectionResizeMode(i, QHeaderView::ResizeToContents);
|
||||
}
|
||||
}
|
||||
@ -633,8 +561,7 @@ ServersPage::ServersPage(InstancePtr inst, QWidget* parent)
|
||||
connect(m_model, &QAbstractItemModel::rowsRemoved, this, &ServersPage::rowsRemoved);
|
||||
|
||||
m_locked = m_inst->isRunning();
|
||||
if(m_locked)
|
||||
{
|
||||
if (m_locked) {
|
||||
m_model->lock();
|
||||
}
|
||||
|
||||
@ -659,40 +586,33 @@ void ServersPage::ShowContextMenu(const QPoint& pos)
|
||||
delete menu;
|
||||
}
|
||||
|
||||
QMenu * ServersPage::createPopupMenu()
|
||||
QMenu* ServersPage::createPopupMenu()
|
||||
{
|
||||
QMenu* filteredMenu = QMainWindow::createPopupMenu();
|
||||
filteredMenu->removeAction( ui->toolBar->toggleViewAction() );
|
||||
filteredMenu->removeAction(ui->toolBar->toggleViewAction());
|
||||
return filteredMenu;
|
||||
}
|
||||
|
||||
void ServersPage::runningStateChanged(bool running)
|
||||
{
|
||||
if(m_locked == running)
|
||||
{
|
||||
if (m_locked == running) {
|
||||
return;
|
||||
}
|
||||
m_locked = running;
|
||||
if(m_locked)
|
||||
{
|
||||
if (m_locked) {
|
||||
m_model->lock();
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
m_model->unlock();
|
||||
}
|
||||
updateState();
|
||||
}
|
||||
|
||||
void ServersPage::currentChanged(const QModelIndex ¤t, const QModelIndex &previous)
|
||||
void ServersPage::currentChanged(const QModelIndex& current, const QModelIndex& previous)
|
||||
{
|
||||
int nextServer = -1;
|
||||
if (!current.isValid())
|
||||
{
|
||||
if (!current.isValid()) {
|
||||
nextServer = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
nextServer = current.row();
|
||||
}
|
||||
currentServer = nextServer;
|
||||
@ -702,18 +622,13 @@ void ServersPage::currentChanged(const QModelIndex ¤t, const QModelIndex &
|
||||
// WARNING: this is here because currentChanged is not accurate when removing rows. the current item needs to be fixed up after removal.
|
||||
void ServersPage::rowsRemoved(const QModelIndex& parent, int first, int last)
|
||||
{
|
||||
if(currentServer < first)
|
||||
{
|
||||
if (currentServer < first) {
|
||||
// current was before the removal
|
||||
return;
|
||||
}
|
||||
else if(currentServer >= first && currentServer <= last)
|
||||
{
|
||||
} else if (currentServer >= first && currentServer <= last) {
|
||||
// current got removed...
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// current was past the removal
|
||||
int count = last - first + 1;
|
||||
currentServer -= count;
|
||||
@ -749,14 +664,11 @@ void ServersPage::updateState()
|
||||
ui->actionRemove->setEnabled(serverEditEnabled);
|
||||
ui->actionJoin->setEnabled(serverEditEnabled);
|
||||
|
||||
if(server)
|
||||
{
|
||||
if (server) {
|
||||
ui->addressLine->setText(server->m_address);
|
||||
ui->nameLine->setText(server->m_name);
|
||||
ui->resourceComboBox->setCurrentIndex(int(server->m_acceptsTextures));
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ui->addressLine->setText(QString());
|
||||
ui->nameLine->setText(QString());
|
||||
ui->resourceComboBox->setCurrentIndex(0);
|
||||
@ -788,27 +700,25 @@ void ServersPage::closedImpl()
|
||||
void ServersPage::on_actionAdd_triggered()
|
||||
{
|
||||
int position = m_model->addEmptyRow(currentServer + 1);
|
||||
if(position < 0)
|
||||
{
|
||||
if (position < 0) {
|
||||
return;
|
||||
}
|
||||
// select the new row
|
||||
ui->serversView->selectionModel()->setCurrentIndex(
|
||||
m_model->index(position),
|
||||
QItemSelectionModel::SelectCurrent | QItemSelectionModel::Clear | QItemSelectionModel::Rows
|
||||
);
|
||||
m_model->index(position), QItemSelectionModel::SelectCurrent | QItemSelectionModel::Clear | QItemSelectionModel::Rows);
|
||||
currentServer = position;
|
||||
}
|
||||
|
||||
void ServersPage::on_actionRemove_triggered()
|
||||
{
|
||||
auto response = CustomMessageBox::selectable(this, tr("Confirm Removal"),
|
||||
tr("You are about to remove \"%1\".\n"
|
||||
"This is permanent and the server will be gone from your list forever (A LONG TIME).\n\n"
|
||||
"Are you sure?")
|
||||
.arg(m_model->at(currentServer)->m_name),
|
||||
QMessageBox::Warning, QMessageBox::Yes | QMessageBox::No, QMessageBox::No)
|
||||
->exec();
|
||||
auto response =
|
||||
CustomMessageBox::selectable(this, tr("Confirm Removal"),
|
||||
tr("You are about to remove \"%1\".\n"
|
||||
"This is permanent and the server will be gone from your list forever (A LONG TIME).\n\n"
|
||||
"Are you sure?")
|
||||
.arg(m_model->at(currentServer)->m_name),
|
||||
QMessageBox::Warning, QMessageBox::Yes | QMessageBox::No, QMessageBox::No)
|
||||
->exec();
|
||||
|
||||
if (response != QMessageBox::Yes)
|
||||
return;
|
||||
@ -818,23 +728,21 @@ void ServersPage::on_actionRemove_triggered()
|
||||
|
||||
void ServersPage::on_actionMove_Up_triggered()
|
||||
{
|
||||
if(m_model->moveUp(currentServer))
|
||||
{
|
||||
currentServer --;
|
||||
if (m_model->moveUp(currentServer)) {
|
||||
currentServer--;
|
||||
}
|
||||
}
|
||||
|
||||
void ServersPage::on_actionMove_Down_triggered()
|
||||
{
|
||||
if(m_model->moveDown(currentServer))
|
||||
{
|
||||
currentServer ++;
|
||||
if (m_model->moveDown(currentServer)) {
|
||||
currentServer++;
|
||||
}
|
||||
}
|
||||
|
||||
void ServersPage::on_actionJoin_triggered()
|
||||
{
|
||||
const auto &address = m_model->at(currentServer)->m_address;
|
||||
const auto& address = m_model->at(currentServer)->m_address;
|
||||
APPLICATION->launch(m_inst, true, false, nullptr, std::make_shared<MinecraftServerTarget>(MinecraftServerTarget::parse(address)));
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
/*
|
||||
* PolyMC - Minecraft Launcher
|
||||
* Prism Launcher - Minecraft Launcher
|
||||
* Copyright (c) 2022 Jamie Mansfield <jmansfield@cadixdev.org>
|
||||
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
|
||||
*
|
||||
@ -39,13 +39,12 @@
|
||||
#include <QMainWindow>
|
||||
#include <QString>
|
||||
|
||||
#include "ui/pages/BasePage.h"
|
||||
#include <Application.h>
|
||||
#include "ui/pages/BasePage.h"
|
||||
|
||||
#include "settings/Setting.h"
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
namespace Ui {
|
||||
class ServersPage;
|
||||
}
|
||||
|
||||
@ -53,46 +52,33 @@ struct Server;
|
||||
class ServersModel;
|
||||
class MinecraftInstance;
|
||||
|
||||
class ServersPage : public QMainWindow, public BasePage
|
||||
{
|
||||
class ServersPage : public QMainWindow, public BasePage {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ServersPage(InstancePtr inst, QWidget *parent = 0);
|
||||
public:
|
||||
explicit ServersPage(InstancePtr inst, QWidget* parent = 0);
|
||||
virtual ~ServersPage();
|
||||
|
||||
void openedImpl() override;
|
||||
void closedImpl() override;
|
||||
|
||||
virtual QString displayName() const override
|
||||
{
|
||||
return tr("Servers");
|
||||
}
|
||||
virtual QIcon icon() const override
|
||||
{
|
||||
return APPLICATION->getThemedIcon("server");
|
||||
}
|
||||
virtual QString id() const override
|
||||
{
|
||||
return "servers";
|
||||
}
|
||||
virtual QString helpPage() const override
|
||||
{
|
||||
return "Servers-management";
|
||||
}
|
||||
virtual QString displayName() const override { return tr("Servers"); }
|
||||
virtual QIcon icon() const override { return APPLICATION->getThemedIcon("server"); }
|
||||
virtual QString id() const override { return "servers"; }
|
||||
virtual QString helpPage() const override { return "Servers-management"; }
|
||||
void retranslate() override;
|
||||
|
||||
protected:
|
||||
QMenu * createPopupMenu() override;
|
||||
protected:
|
||||
QMenu* createPopupMenu() override;
|
||||
|
||||
private:
|
||||
private:
|
||||
void updateState();
|
||||
void scheduleSave();
|
||||
bool saveIsScheduled() const;
|
||||
|
||||
private slots:
|
||||
void currentChanged(const QModelIndex ¤t, const QModelIndex &previous);
|
||||
void rowsRemoved(const QModelIndex &parent, int first, int last);
|
||||
private slots:
|
||||
void currentChanged(const QModelIndex& current, const QModelIndex& previous);
|
||||
void rowsRemoved(const QModelIndex& parent, int first, int last);
|
||||
|
||||
void on_actionAdd_triggered();
|
||||
void on_actionRemove_triggered();
|
||||
@ -102,19 +88,18 @@ private slots:
|
||||
|
||||
void runningStateChanged(bool running);
|
||||
|
||||
void nameEdited(const QString & name);
|
||||
void addressEdited(const QString & address);
|
||||
void resourceIndexChanged(int index);\
|
||||
void nameEdited(const QString& name);
|
||||
void addressEdited(const QString& address);
|
||||
void resourceIndexChanged(int index);
|
||||
|
||||
void ShowContextMenu(const QPoint &pos);
|
||||
void ShowContextMenu(const QPoint& pos);
|
||||
|
||||
private: // data
|
||||
private: // data
|
||||
int currentServer = -1;
|
||||
bool m_locked = true;
|
||||
Ui::ServersPage *ui = nullptr;
|
||||
ServersModel * m_model = nullptr;
|
||||
Ui::ServersPage* ui = nullptr;
|
||||
ServersModel* m_model = nullptr;
|
||||
InstancePtr m_inst = nullptr;
|
||||
|
||||
std::shared_ptr<Setting> m_wide_bar_setting = nullptr;
|
||||
};
|
||||
|
||||
|
@ -39,11 +39,10 @@
|
||||
|
||||
#include "ExternalResourcesPage.h"
|
||||
|
||||
class ShaderPackPage : public ExternalResourcesPage
|
||||
{
|
||||
class ShaderPackPage : public ExternalResourcesPage {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ShaderPackPage(MinecraftInstance *instance, std::shared_ptr<ShaderPackFolderModel> model, QWidget *parent = nullptr);
|
||||
public:
|
||||
explicit ShaderPackPage(MinecraftInstance* instance, std::shared_ptr<ShaderPackFolderModel> model, QWidget* parent = nullptr);
|
||||
~ShaderPackPage() override = default;
|
||||
|
||||
QString displayName() const override { return tr("Shader packs"); }
|
||||
|
@ -42,21 +42,17 @@
|
||||
|
||||
#include "minecraft/mod/TexturePackFolderModel.h"
|
||||
|
||||
class TexturePackPage : public ExternalResourcesPage
|
||||
{
|
||||
class TexturePackPage : public ExternalResourcesPage {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit TexturePackPage(MinecraftInstance *instance, std::shared_ptr<TexturePackFolderModel> model, QWidget* parent = nullptr);
|
||||
public:
|
||||
explicit TexturePackPage(MinecraftInstance* instance, std::shared_ptr<TexturePackFolderModel> model, QWidget* parent = nullptr);
|
||||
|
||||
QString displayName() const override { return tr("Texture packs"); }
|
||||
QIcon icon() const override { return APPLICATION->getThemedIcon("resourcepacks"); }
|
||||
QString id() const override { return "texturepacks"; }
|
||||
QString helpPage() const override { return "Texture-packs"; }
|
||||
|
||||
virtual bool shouldDisplay() const override
|
||||
{
|
||||
return m_instance->traits().contains("texturepacks");
|
||||
}
|
||||
virtual bool shouldDisplay() const override { return m_instance->traits().contains("texturepacks"); }
|
||||
|
||||
public slots:
|
||||
bool onSelectionChanged(const QModelIndex& current, const QModelIndex& previous) override;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user