NOISSUE tabs -> spaces
This commit is contained in:
@ -15,237 +15,237 @@
|
||||
#include <widgets/CustomCommands.h>
|
||||
|
||||
InstanceSettingsPage::InstanceSettingsPage(BaseInstance *inst, QWidget *parent)
|
||||
: QWidget(parent), ui(new Ui::InstanceSettingsPage), m_instance(inst)
|
||||
: QWidget(parent), ui(new Ui::InstanceSettingsPage), m_instance(inst)
|
||||
{
|
||||
m_settings = inst->settings();
|
||||
ui->setupUi(this);
|
||||
auto sysMB = Sys::getSystemRam() / Sys::megabyte;
|
||||
ui->maxMemSpinBox->setMaximum(sysMB);
|
||||
loadSettings();
|
||||
m_settings = inst->settings();
|
||||
ui->setupUi(this);
|
||||
auto sysMB = Sys::getSystemRam() / Sys::megabyte;
|
||||
ui->maxMemSpinBox->setMaximum(sysMB);
|
||||
loadSettings();
|
||||
}
|
||||
|
||||
bool InstanceSettingsPage::shouldDisplay() const
|
||||
{
|
||||
return !m_instance->isRunning();
|
||||
return !m_instance->isRunning();
|
||||
}
|
||||
|
||||
InstanceSettingsPage::~InstanceSettingsPage()
|
||||
{
|
||||
delete ui;
|
||||
delete ui;
|
||||
}
|
||||
|
||||
bool InstanceSettingsPage::apply()
|
||||
{
|
||||
applySettings();
|
||||
return true;
|
||||
applySettings();
|
||||
return true;
|
||||
}
|
||||
|
||||
void InstanceSettingsPage::applySettings()
|
||||
{
|
||||
SettingsObject::Lock lock(m_settings);
|
||||
SettingsObject::Lock lock(m_settings);
|
||||
|
||||
// Console
|
||||
bool console = ui->consoleSettingsBox->isChecked();
|
||||
m_settings->set("OverrideConsole", 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
|
||||
{
|
||||
m_settings->reset("ShowConsole");
|
||||
m_settings->reset("AutoCloseConsole");
|
||||
m_settings->reset("ShowConsoleOnError");
|
||||
}
|
||||
// Console
|
||||
bool console = ui->consoleSettingsBox->isChecked();
|
||||
m_settings->set("OverrideConsole", 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
|
||||
{
|
||||
m_settings->reset("ShowConsole");
|
||||
m_settings->reset("AutoCloseConsole");
|
||||
m_settings->reset("ShowConsoleOnError");
|
||||
}
|
||||
|
||||
// Window Size
|
||||
bool window = ui->windowSizeGroupBox->isChecked();
|
||||
m_settings->set("OverrideWindow", 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
|
||||
{
|
||||
m_settings->reset("LaunchMaximized");
|
||||
m_settings->reset("MinecraftWinWidth");
|
||||
m_settings->reset("MinecraftWinHeight");
|
||||
}
|
||||
// Window Size
|
||||
bool window = ui->windowSizeGroupBox->isChecked();
|
||||
m_settings->set("OverrideWindow", 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
|
||||
{
|
||||
m_settings->reset("LaunchMaximized");
|
||||
m_settings->reset("MinecraftWinWidth");
|
||||
m_settings->reset("MinecraftWinHeight");
|
||||
}
|
||||
|
||||
// Memory
|
||||
bool memory = ui->memoryGroupBox->isChecked();
|
||||
m_settings->set("OverrideMemory", memory);
|
||||
if (memory)
|
||||
{
|
||||
int min = ui->minMemSpinBox->value();
|
||||
int max = ui->maxMemSpinBox->value();
|
||||
if(min < max)
|
||||
{
|
||||
m_settings->set("MinMemAlloc", min);
|
||||
m_settings->set("MaxMemAlloc", max);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_settings->set("MinMemAlloc", max);
|
||||
m_settings->set("MaxMemAlloc", min);
|
||||
}
|
||||
m_settings->set("PermGen", ui->permGenSpinBox->value());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_settings->reset("MinMemAlloc");
|
||||
m_settings->reset("MaxMemAlloc");
|
||||
m_settings->reset("PermGen");
|
||||
}
|
||||
// Memory
|
||||
bool memory = ui->memoryGroupBox->isChecked();
|
||||
m_settings->set("OverrideMemory", memory);
|
||||
if (memory)
|
||||
{
|
||||
int min = ui->minMemSpinBox->value();
|
||||
int max = ui->maxMemSpinBox->value();
|
||||
if(min < max)
|
||||
{
|
||||
m_settings->set("MinMemAlloc", min);
|
||||
m_settings->set("MaxMemAlloc", max);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_settings->set("MinMemAlloc", max);
|
||||
m_settings->set("MaxMemAlloc", min);
|
||||
}
|
||||
m_settings->set("PermGen", ui->permGenSpinBox->value());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_settings->reset("MinMemAlloc");
|
||||
m_settings->reset("MaxMemAlloc");
|
||||
m_settings->reset("PermGen");
|
||||
}
|
||||
|
||||
// Java Install Settings
|
||||
bool javaInstall = ui->javaSettingsGroupBox->isChecked();
|
||||
m_settings->set("OverrideJavaLocation", javaInstall);
|
||||
if (javaInstall)
|
||||
{
|
||||
m_settings->set("JavaPath", ui->javaPathTextBox->text());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_settings->reset("JavaPath");
|
||||
}
|
||||
// Java Install Settings
|
||||
bool javaInstall = ui->javaSettingsGroupBox->isChecked();
|
||||
m_settings->set("OverrideJavaLocation", javaInstall);
|
||||
if (javaInstall)
|
||||
{
|
||||
m_settings->set("JavaPath", ui->javaPathTextBox->text());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_settings->reset("JavaPath");
|
||||
}
|
||||
|
||||
// Java arguments
|
||||
bool javaArgs = ui->javaArgumentsGroupBox->isChecked();
|
||||
m_settings->set("OverrideJavaArgs", javaArgs);
|
||||
if(javaArgs)
|
||||
{
|
||||
m_settings->set("JvmArgs", ui->jvmArgsTextBox->toPlainText().replace("\n", " "));
|
||||
JavaCommon::checkJVMArgs(m_settings->get("JvmArgs").toString(), this->parentWidget());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_settings->reset("JvmArgs");
|
||||
}
|
||||
// Java arguments
|
||||
bool javaArgs = ui->javaArgumentsGroupBox->isChecked();
|
||||
m_settings->set("OverrideJavaArgs", javaArgs);
|
||||
if(javaArgs)
|
||||
{
|
||||
m_settings->set("JvmArgs", ui->jvmArgsTextBox->toPlainText().replace("\n", " "));
|
||||
JavaCommon::checkJVMArgs(m_settings->get("JvmArgs").toString(), this->parentWidget());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_settings->reset("JvmArgs");
|
||||
}
|
||||
|
||||
// old generic 'override both' is removed.
|
||||
m_settings->reset("OverrideJava");
|
||||
// old generic 'override both' is removed.
|
||||
m_settings->reset("OverrideJava");
|
||||
|
||||
// Custom Commands
|
||||
bool custcmd = ui->customCommands->checked();
|
||||
m_settings->set("OverrideCommands", 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
|
||||
{
|
||||
m_settings->reset("PreLaunchCommand");
|
||||
m_settings->reset("WrapperCommand");
|
||||
m_settings->reset("PostExitCommand");
|
||||
}
|
||||
// Custom Commands
|
||||
bool custcmd = ui->customCommands->checked();
|
||||
m_settings->set("OverrideCommands", 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
|
||||
{
|
||||
m_settings->reset("PreLaunchCommand");
|
||||
m_settings->reset("WrapperCommand");
|
||||
m_settings->reset("PostExitCommand");
|
||||
}
|
||||
}
|
||||
|
||||
void InstanceSettingsPage::loadSettings()
|
||||
{
|
||||
// Console
|
||||
ui->consoleSettingsBox->setChecked(m_settings->get("OverrideConsole").toBool());
|
||||
ui->showConsoleCheck->setChecked(m_settings->get("ShowConsole").toBool());
|
||||
ui->autoCloseConsoleCheck->setChecked(m_settings->get("AutoCloseConsole").toBool());
|
||||
ui->showConsoleErrorCheck->setChecked(m_settings->get("ShowConsoleOnError").toBool());
|
||||
// Console
|
||||
ui->consoleSettingsBox->setChecked(m_settings->get("OverrideConsole").toBool());
|
||||
ui->showConsoleCheck->setChecked(m_settings->get("ShowConsole").toBool());
|
||||
ui->autoCloseConsoleCheck->setChecked(m_settings->get("AutoCloseConsole").toBool());
|
||||
ui->showConsoleErrorCheck->setChecked(m_settings->get("ShowConsoleOnError").toBool());
|
||||
|
||||
// Window Size
|
||||
ui->windowSizeGroupBox->setChecked(m_settings->get("OverrideWindow").toBool());
|
||||
ui->maximizedCheckBox->setChecked(m_settings->get("LaunchMaximized").toBool());
|
||||
ui->windowWidthSpinBox->setValue(m_settings->get("MinecraftWinWidth").toInt());
|
||||
ui->windowHeightSpinBox->setValue(m_settings->get("MinecraftWinHeight").toInt());
|
||||
// Window Size
|
||||
ui->windowSizeGroupBox->setChecked(m_settings->get("OverrideWindow").toBool());
|
||||
ui->maximizedCheckBox->setChecked(m_settings->get("LaunchMaximized").toBool());
|
||||
ui->windowWidthSpinBox->setValue(m_settings->get("MinecraftWinWidth").toInt());
|
||||
ui->windowHeightSpinBox->setValue(m_settings->get("MinecraftWinHeight").toInt());
|
||||
|
||||
// Memory
|
||||
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)
|
||||
{
|
||||
ui->minMemSpinBox->setValue(min);
|
||||
ui->maxMemSpinBox->setValue(max);
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->minMemSpinBox->setValue(max);
|
||||
ui->maxMemSpinBox->setValue(min);
|
||||
}
|
||||
ui->permGenSpinBox->setValue(m_settings->get("PermGen").toInt());
|
||||
// Memory
|
||||
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)
|
||||
{
|
||||
ui->minMemSpinBox->setValue(min);
|
||||
ui->maxMemSpinBox->setValue(max);
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->minMemSpinBox->setValue(max);
|
||||
ui->maxMemSpinBox->setValue(min);
|
||||
}
|
||||
ui->permGenSpinBox->setValue(m_settings->get("PermGen").toInt());
|
||||
|
||||
// Java Settings
|
||||
bool overrideJava = m_settings->get("OverrideJava").toBool();
|
||||
bool overrideLocation = m_settings->get("OverrideJavaLocation").toBool() || overrideJava;
|
||||
bool overrideArgs = m_settings->get("OverrideJavaArgs").toBool() || overrideJava;
|
||||
// Java Settings
|
||||
bool overrideJava = m_settings->get("OverrideJava").toBool();
|
||||
bool overrideLocation = m_settings->get("OverrideJavaLocation").toBool() || overrideJava;
|
||||
bool overrideArgs = m_settings->get("OverrideJavaArgs").toBool() || overrideJava;
|
||||
|
||||
ui->javaSettingsGroupBox->setChecked(overrideLocation);
|
||||
ui->javaPathTextBox->setText(m_settings->get("JavaPath").toString());
|
||||
ui->javaSettingsGroupBox->setChecked(overrideLocation);
|
||||
ui->javaPathTextBox->setText(m_settings->get("JavaPath").toString());
|
||||
|
||||
ui->javaArgumentsGroupBox->setChecked(overrideArgs);
|
||||
ui->jvmArgsTextBox->setPlainText(m_settings->get("JvmArgs").toString());
|
||||
ui->javaArgumentsGroupBox->setChecked(overrideArgs);
|
||||
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()
|
||||
);
|
||||
// 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()
|
||||
);
|
||||
}
|
||||
|
||||
void InstanceSettingsPage::on_javaDetectBtn_clicked()
|
||||
{
|
||||
JavaInstallPtr java;
|
||||
JavaInstallPtr java;
|
||||
|
||||
VersionSelectDialog vselect(MMC->javalist().get(), tr("Select a Java version"), this, true);
|
||||
vselect.setResizeOn(2);
|
||||
vselect.exec();
|
||||
VersionSelectDialog vselect(MMC->javalist().get(), tr("Select a Java version"), this, true);
|
||||
vselect.setResizeOn(2);
|
||||
vselect.exec();
|
||||
|
||||
if (vselect.result() == QDialog::Accepted && vselect.selectedVersion())
|
||||
{
|
||||
java = std::dynamic_pointer_cast<JavaInstall>(vselect.selectedVersion());
|
||||
ui->javaPathTextBox->setText(java->path);
|
||||
}
|
||||
if (vselect.result() == QDialog::Accepted && vselect.selectedVersion())
|
||||
{
|
||||
java = std::dynamic_pointer_cast<JavaInstall>(vselect.selectedVersion());
|
||||
ui->javaPathTextBox->setText(java->path);
|
||||
}
|
||||
}
|
||||
|
||||
void InstanceSettingsPage::on_javaBrowseBtn_clicked()
|
||||
{
|
||||
QString raw_path = QFileDialog::getOpenFileName(this, tr("Find Java executable"));
|
||||
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())
|
||||
{
|
||||
return;
|
||||
}
|
||||
QString cooked_path = FS::NormalizePath(raw_path);
|
||||
// do not allow current dir - it's dirty. Do not allow dirs that don't exist
|
||||
if(raw_path.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
QString cooked_path = FS::NormalizePath(raw_path);
|
||||
|
||||
QFileInfo javaInfo(cooked_path);;
|
||||
if(!javaInfo.exists() || !javaInfo.isExecutable())
|
||||
{
|
||||
return;
|
||||
}
|
||||
ui->javaPathTextBox->setText(cooked_path);
|
||||
QFileInfo javaInfo(cooked_path);;
|
||||
if(!javaInfo.exists() || !javaInfo.isExecutable())
|
||||
{
|
||||
return;
|
||||
}
|
||||
ui->javaPathTextBox->setText(cooked_path);
|
||||
}
|
||||
|
||||
void InstanceSettingsPage::on_javaTestBtn_clicked()
|
||||
{
|
||||
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()));
|
||||
connect(checker.get(), SIGNAL(finished()), SLOT(checkerFinished()));
|
||||
checker->run();
|
||||
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()));
|
||||
connect(checker.get(), SIGNAL(finished()), SLOT(checkerFinished()));
|
||||
checker->run();
|
||||
}
|
||||
|
||||
void InstanceSettingsPage::checkerFinished()
|
||||
{
|
||||
checker.reset();
|
||||
checker.reset();
|
||||
}
|
||||
|
@ -32,43 +32,43 @@ class InstanceSettingsPage;
|
||||
|
||||
class InstanceSettingsPage : public QWidget, public BasePage
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit InstanceSettingsPage(BaseInstance *inst, QWidget *parent = 0);
|
||||
virtual ~InstanceSettingsPage();
|
||||
virtual QString displayName() const override
|
||||
{
|
||||
return tr("Settings");
|
||||
}
|
||||
virtual QIcon icon() const override
|
||||
{
|
||||
return MMC->getThemedIcon("instance-settings");
|
||||
}
|
||||
virtual QString id() const override
|
||||
{
|
||||
return "settings";
|
||||
}
|
||||
virtual bool apply() override;
|
||||
virtual QString helpPage() const override
|
||||
{
|
||||
return "Instance-settings";
|
||||
}
|
||||
virtual bool shouldDisplay() const override;
|
||||
explicit InstanceSettingsPage(BaseInstance *inst, QWidget *parent = 0);
|
||||
virtual ~InstanceSettingsPage();
|
||||
virtual QString displayName() const override
|
||||
{
|
||||
return tr("Settings");
|
||||
}
|
||||
virtual QIcon icon() const override
|
||||
{
|
||||
return MMC->getThemedIcon("instance-settings");
|
||||
}
|
||||
virtual QString id() const override
|
||||
{
|
||||
return "settings";
|
||||
}
|
||||
virtual bool apply() override;
|
||||
virtual QString helpPage() const override
|
||||
{
|
||||
return "Instance-settings";
|
||||
}
|
||||
virtual bool shouldDisplay() const override;
|
||||
|
||||
private slots:
|
||||
void on_javaDetectBtn_clicked();
|
||||
void on_javaTestBtn_clicked();
|
||||
void on_javaBrowseBtn_clicked();
|
||||
void on_javaDetectBtn_clicked();
|
||||
void on_javaTestBtn_clicked();
|
||||
void on_javaBrowseBtn_clicked();
|
||||
|
||||
void applySettings();
|
||||
void loadSettings();
|
||||
void applySettings();
|
||||
void loadSettings();
|
||||
|
||||
void checkerFinished();
|
||||
void checkerFinished();
|
||||
|
||||
private:
|
||||
Ui::InstanceSettingsPage *ui;
|
||||
BaseInstance *m_instance;
|
||||
SettingsObjectPtr m_settings;
|
||||
unique_qobject_ptr<JavaCommon::TestCheck> checker;
|
||||
Ui::InstanceSettingsPage *ui;
|
||||
BaseInstance *m_instance;
|
||||
SettingsObjectPtr m_settings;
|
||||
unique_qobject_ptr<JavaCommon::TestCheck> checker;
|
||||
};
|
||||
|
@ -9,42 +9,42 @@
|
||||
#include "dialogs/ProgressDialog.h"
|
||||
|
||||
LegacyUpgradePage::LegacyUpgradePage(InstancePtr inst, QWidget *parent)
|
||||
: QWidget(parent), ui(new Ui::LegacyUpgradePage), m_inst(inst)
|
||||
: QWidget(parent), ui(new Ui::LegacyUpgradePage), m_inst(inst)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
LegacyUpgradePage::~LegacyUpgradePage()
|
||||
{
|
||||
delete ui;
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void LegacyUpgradePage::runModalTask(Task *task)
|
||||
{
|
||||
connect(task, &Task::failed, [this](QString reason)
|
||||
{
|
||||
CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Warning)->show();
|
||||
});
|
||||
ProgressDialog loadDialog(this);
|
||||
loadDialog.setSkipButton(true, tr("Abort"));
|
||||
if(loadDialog.execWithTask(task) == QDialog::Accepted)
|
||||
{
|
||||
m_container->requestClose();
|
||||
}
|
||||
connect(task, &Task::failed, [this](QString reason)
|
||||
{
|
||||
CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Warning)->show();
|
||||
});
|
||||
ProgressDialog loadDialog(this);
|
||||
loadDialog.setSkipButton(true, tr("Abort"));
|
||||
if(loadDialog.execWithTask(task) == QDialog::Accepted)
|
||||
{
|
||||
m_container->requestClose();
|
||||
}
|
||||
}
|
||||
|
||||
void LegacyUpgradePage::on_upgradeButton_clicked()
|
||||
{
|
||||
QString newName = tr("%1 (Migrated)").arg(m_inst->name());
|
||||
auto upgradeTask = new LegacyUpgradeTask(m_inst);
|
||||
upgradeTask->setName(newName);
|
||||
upgradeTask->setGroup(m_inst->group());
|
||||
upgradeTask->setIcon(m_inst->iconKey());
|
||||
std::unique_ptr<Task> task(MMC->folderProvider()->wrapInstanceTask(upgradeTask));
|
||||
runModalTask(task.get());
|
||||
QString newName = tr("%1 (Migrated)").arg(m_inst->name());
|
||||
auto upgradeTask = new LegacyUpgradeTask(m_inst);
|
||||
upgradeTask->setName(newName);
|
||||
upgradeTask->setGroup(m_inst->group());
|
||||
upgradeTask->setIcon(m_inst->iconKey());
|
||||
std::unique_ptr<Task> task(MMC->folderProvider()->wrapInstanceTask(upgradeTask));
|
||||
runModalTask(task.get());
|
||||
}
|
||||
|
||||
bool LegacyUpgradePage::shouldDisplay() const
|
||||
{
|
||||
return !m_inst->isRunning();
|
||||
return !m_inst->isRunning();
|
||||
}
|
||||
|
@ -29,36 +29,36 @@ class LegacyUpgradePage;
|
||||
|
||||
class LegacyUpgradePage : public QWidget, public BasePage
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit LegacyUpgradePage(InstancePtr inst, QWidget *parent = 0);
|
||||
virtual ~LegacyUpgradePage();
|
||||
virtual QString displayName() const override
|
||||
{
|
||||
return tr("Upgrade");
|
||||
}
|
||||
virtual QIcon icon() const override
|
||||
{
|
||||
return MMC->getThemedIcon("checkupdate");
|
||||
}
|
||||
virtual QString id() const override
|
||||
{
|
||||
return "upgrade";
|
||||
}
|
||||
virtual QString helpPage() const override
|
||||
{
|
||||
return "Legacy-upgrade";
|
||||
}
|
||||
virtual bool shouldDisplay() const override;
|
||||
explicit LegacyUpgradePage(InstancePtr inst, QWidget *parent = 0);
|
||||
virtual ~LegacyUpgradePage();
|
||||
virtual QString displayName() const override
|
||||
{
|
||||
return tr("Upgrade");
|
||||
}
|
||||
virtual QIcon icon() const override
|
||||
{
|
||||
return MMC->getThemedIcon("checkupdate");
|
||||
}
|
||||
virtual QString id() const override
|
||||
{
|
||||
return "upgrade";
|
||||
}
|
||||
virtual QString helpPage() const override
|
||||
{
|
||||
return "Legacy-upgrade";
|
||||
}
|
||||
virtual bool shouldDisplay() const override;
|
||||
|
||||
private slots:
|
||||
void on_upgradeButton_clicked();
|
||||
void on_upgradeButton_clicked();
|
||||
|
||||
private:
|
||||
void runModalTask(Task *task);
|
||||
void runModalTask(Task *task);
|
||||
|
||||
private:
|
||||
Ui::LegacyUpgradePage *ui;
|
||||
InstancePtr m_inst;
|
||||
Ui::LegacyUpgradePage *ui;
|
||||
InstancePtr m_inst;
|
||||
};
|
||||
|
@ -15,298 +15,298 @@
|
||||
class LogFormatProxyModel : public QIdentityProxyModel
|
||||
{
|
||||
public:
|
||||
LogFormatProxyModel(QObject* parent = nullptr) : QIdentityProxyModel(parent)
|
||||
{
|
||||
}
|
||||
QVariant data(const QModelIndex &index, int role) const override
|
||||
{
|
||||
switch(role)
|
||||
{
|
||||
case Qt::FontRole:
|
||||
return m_font;
|
||||
case Qt::TextColorRole:
|
||||
{
|
||||
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();
|
||||
return m_colors->getBack(level);
|
||||
}
|
||||
default:
|
||||
return QIdentityProxyModel::data(index, role);
|
||||
}
|
||||
}
|
||||
LogFormatProxyModel(QObject* parent = nullptr) : QIdentityProxyModel(parent)
|
||||
{
|
||||
}
|
||||
QVariant data(const QModelIndex &index, int role) const override
|
||||
{
|
||||
switch(role)
|
||||
{
|
||||
case Qt::FontRole:
|
||||
return m_font;
|
||||
case Qt::TextColorRole:
|
||||
{
|
||||
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();
|
||||
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 parentIndex = parent(start);
|
||||
auto compare = [&](int r) -> QModelIndex
|
||||
{
|
||||
QModelIndex idx = index(r, start.column(), parentIndex);
|
||||
if (!idx.isValid() || idx == start)
|
||||
{
|
||||
return QModelIndex();
|
||||
}
|
||||
QVariant v = data(idx, Qt::DisplayRole);
|
||||
QString t = v.toString();
|
||||
if (t.contains(value, Qt::CaseInsensitive))
|
||||
return idx;
|
||||
return QModelIndex();
|
||||
};
|
||||
if(reverse)
|
||||
{
|
||||
int from = start.row();
|
||||
int to = 0;
|
||||
QModelIndex find(const QModelIndex &start, const QString &value, bool reverse) const
|
||||
{
|
||||
QModelIndex parentIndex = parent(start);
|
||||
auto compare = [&](int r) -> QModelIndex
|
||||
{
|
||||
QModelIndex idx = index(r, start.column(), parentIndex);
|
||||
if (!idx.isValid() || idx == start)
|
||||
{
|
||||
return QModelIndex();
|
||||
}
|
||||
QVariant v = data(idx, Qt::DisplayRole);
|
||||
QString t = v.toString();
|
||||
if (t.contains(value, Qt::CaseInsensitive))
|
||||
return idx;
|
||||
return QModelIndex();
|
||||
};
|
||||
if(reverse)
|
||||
{
|
||||
int from = start.row();
|
||||
int to = 0;
|
||||
|
||||
for (int i = 0; i < 2; ++i)
|
||||
{
|
||||
for (int r = from; (r >= to); --r)
|
||||
{
|
||||
auto idx = compare(r);
|
||||
if(idx.isValid())
|
||||
return idx;
|
||||
}
|
||||
// prepare for the next iteration
|
||||
from = rowCount() - 1;
|
||||
to = start.row();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int from = start.row();
|
||||
int to = rowCount(parentIndex);
|
||||
for (int i = 0; i < 2; ++i)
|
||||
{
|
||||
for (int r = from; (r >= to); --r)
|
||||
{
|
||||
auto idx = compare(r);
|
||||
if(idx.isValid())
|
||||
return idx;
|
||||
}
|
||||
// prepare for the next iteration
|
||||
from = rowCount() - 1;
|
||||
to = start.row();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int from = start.row();
|
||||
int to = rowCount(parentIndex);
|
||||
|
||||
for (int i = 0; i < 2; ++i)
|
||||
{
|
||||
for (int r = from; (r < to); ++r)
|
||||
{
|
||||
auto idx = compare(r);
|
||||
if(idx.isValid())
|
||||
return idx;
|
||||
}
|
||||
// prepare for the next iteration
|
||||
from = 0;
|
||||
to = start.row();
|
||||
}
|
||||
}
|
||||
return QModelIndex();
|
||||
}
|
||||
for (int i = 0; i < 2; ++i)
|
||||
{
|
||||
for (int r = from; (r < to); ++r)
|
||||
{
|
||||
auto idx = compare(r);
|
||||
if(idx.isValid())
|
||||
return idx;
|
||||
}
|
||||
// prepare for the next iteration
|
||||
from = 0;
|
||||
to = start.row();
|
||||
}
|
||||
}
|
||||
return QModelIndex();
|
||||
}
|
||||
private:
|
||||
QFont m_font;
|
||||
std::unique_ptr<LogColorCache> m_colors;
|
||||
QFont m_font;
|
||||
std::unique_ptr<LogColorCache> m_colors;
|
||||
};
|
||||
|
||||
LogPage::LogPage(InstancePtr instance, QWidget *parent)
|
||||
: QWidget(parent), ui(new Ui::LogPage), m_instance(instance)
|
||||
: QWidget(parent), ui(new Ui::LogPage), m_instance(instance)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->tabWidget->tabBar()->hide();
|
||||
ui->setupUi(this);
|
||||
ui->tabWidget->tabBar()->hide();
|
||||
|
||||
m_proxy = new LogFormatProxyModel(this);
|
||||
// set up text colors in the log proxy and adapt them to the current theme foreground and background
|
||||
{
|
||||
auto origForeground = ui->text->palette().color(ui->text->foregroundRole());
|
||||
auto origBackground = ui->text->palette().color(ui->text->backgroundRole());
|
||||
m_proxy->setColors(new LogColorCache(origForeground, origBackground));
|
||||
}
|
||||
m_proxy = new LogFormatProxyModel(this);
|
||||
// set up text colors in the log proxy and adapt them to the current theme foreground and background
|
||||
{
|
||||
auto origForeground = ui->text->palette().color(ui->text->foregroundRole());
|
||||
auto origBackground = ui->text->palette().color(ui->text->backgroundRole());
|
||||
m_proxy->setColors(new LogColorCache(origForeground, origBackground));
|
||||
}
|
||||
|
||||
// set up fonts in the log proxy
|
||||
{
|
||||
QString fontFamily = MMC->settings()->get("ConsoleFont").toString();
|
||||
bool conversionOk = false;
|
||||
int fontSize = MMC->settings()->get("ConsoleFontSize").toInt(&conversionOk);
|
||||
if(!conversionOk)
|
||||
{
|
||||
fontSize = 11;
|
||||
}
|
||||
m_proxy->setFont(QFont(fontFamily, fontSize));
|
||||
}
|
||||
// set up fonts in the log proxy
|
||||
{
|
||||
QString fontFamily = MMC->settings()->get("ConsoleFont").toString();
|
||||
bool conversionOk = false;
|
||||
int fontSize = MMC->settings()->get("ConsoleFontSize").toInt(&conversionOk);
|
||||
if(!conversionOk)
|
||||
{
|
||||
fontSize = 11;
|
||||
}
|
||||
m_proxy->setFont(QFont(fontFamily, fontSize));
|
||||
}
|
||||
|
||||
ui->text->setModel(m_proxy);
|
||||
ui->text->setModel(m_proxy);
|
||||
|
||||
// set up instance and launch process recognition
|
||||
{
|
||||
auto launchTask = m_instance->getLaunchTask();
|
||||
if(launchTask)
|
||||
{
|
||||
setInstanceLaunchTaskChanged(launchTask, true);
|
||||
}
|
||||
connect(m_instance.get(), &BaseInstance::launchTaskChanged, this, &LogPage::onInstanceLaunchTaskChanged);
|
||||
}
|
||||
// set up instance and launch process recognition
|
||||
{
|
||||
auto launchTask = m_instance->getLaunchTask();
|
||||
if(launchTask)
|
||||
{
|
||||
setInstanceLaunchTaskChanged(launchTask, true);
|
||||
}
|
||||
connect(m_instance.get(), &BaseInstance::launchTaskChanged, this, &LogPage::onInstanceLaunchTaskChanged);
|
||||
}
|
||||
|
||||
auto findShortcut = new QShortcut(QKeySequence(QKeySequence::Find), this);
|
||||
connect(findShortcut, SIGNAL(activated()), SLOT(findActivated()));
|
||||
auto findNextShortcut = new QShortcut(QKeySequence(QKeySequence::FindNext), this);
|
||||
connect(findNextShortcut, SIGNAL(activated()), SLOT(findNextActivated()));
|
||||
connect(ui->searchBar, SIGNAL(returnPressed()), SLOT(on_findButton_clicked()));
|
||||
auto findPreviousShortcut = new QShortcut(QKeySequence(QKeySequence::FindPrevious), this);
|
||||
connect(findPreviousShortcut, SIGNAL(activated()), SLOT(findPreviousActivated()));
|
||||
auto findShortcut = new QShortcut(QKeySequence(QKeySequence::Find), this);
|
||||
connect(findShortcut, SIGNAL(activated()), SLOT(findActivated()));
|
||||
auto findNextShortcut = new QShortcut(QKeySequence(QKeySequence::FindNext), this);
|
||||
connect(findNextShortcut, SIGNAL(activated()), SLOT(findNextActivated()));
|
||||
connect(ui->searchBar, SIGNAL(returnPressed()), SLOT(on_findButton_clicked()));
|
||||
auto findPreviousShortcut = new QShortcut(QKeySequence(QKeySequence::FindPrevious), this);
|
||||
connect(findPreviousShortcut, SIGNAL(activated()), SLOT(findPreviousActivated()));
|
||||
}
|
||||
|
||||
LogPage::~LogPage()
|
||||
{
|
||||
delete ui;
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void LogPage::modelStateToUI()
|
||||
{
|
||||
if(m_model->wrapLines())
|
||||
{
|
||||
ui->text->setWordWrap(true);
|
||||
ui->wrapCheckbox->setCheckState(Qt::Checked);
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->text->setWordWrap(false);
|
||||
ui->wrapCheckbox->setCheckState(Qt::Unchecked);
|
||||
}
|
||||
if(m_model->suspended())
|
||||
{
|
||||
ui->trackLogCheckbox->setCheckState(Qt::Unchecked);
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->trackLogCheckbox->setCheckState(Qt::Checked);
|
||||
}
|
||||
if(m_model->wrapLines())
|
||||
{
|
||||
ui->text->setWordWrap(true);
|
||||
ui->wrapCheckbox->setCheckState(Qt::Checked);
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->text->setWordWrap(false);
|
||||
ui->wrapCheckbox->setCheckState(Qt::Unchecked);
|
||||
}
|
||||
if(m_model->suspended())
|
||||
{
|
||||
ui->trackLogCheckbox->setCheckState(Qt::Unchecked);
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->trackLogCheckbox->setCheckState(Qt::Checked);
|
||||
}
|
||||
}
|
||||
|
||||
void LogPage::UIToModelState()
|
||||
{
|
||||
if(!m_model)
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_model->setLineWrap(ui->wrapCheckbox->checkState() == Qt::Checked);
|
||||
m_model->suspend(ui->trackLogCheckbox->checkState() != Qt::Checked);
|
||||
if(!m_model)
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_model->setLineWrap(ui->wrapCheckbox->checkState() == Qt::Checked);
|
||||
m_model->suspend(ui->trackLogCheckbox->checkState() != Qt::Checked);
|
||||
}
|
||||
|
||||
void LogPage::setInstanceLaunchTaskChanged(std::shared_ptr<LaunchTask> proc, bool initial)
|
||||
{
|
||||
m_process = proc;
|
||||
if(m_process)
|
||||
{
|
||||
m_model = proc->getLogModel();
|
||||
m_proxy->setSourceModel(m_model.get());
|
||||
if(initial)
|
||||
{
|
||||
modelStateToUI();
|
||||
}
|
||||
else
|
||||
{
|
||||
UIToModelState();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_proxy->setSourceModel(nullptr);
|
||||
m_model.reset();
|
||||
}
|
||||
m_process = proc;
|
||||
if(m_process)
|
||||
{
|
||||
m_model = proc->getLogModel();
|
||||
m_proxy->setSourceModel(m_model.get());
|
||||
if(initial)
|
||||
{
|
||||
modelStateToUI();
|
||||
}
|
||||
else
|
||||
{
|
||||
UIToModelState();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_proxy->setSourceModel(nullptr);
|
||||
m_model.reset();
|
||||
}
|
||||
}
|
||||
|
||||
void LogPage::onInstanceLaunchTaskChanged(std::shared_ptr<LaunchTask> proc)
|
||||
{
|
||||
setInstanceLaunchTaskChanged(proc, false);
|
||||
setInstanceLaunchTaskChanged(proc, false);
|
||||
}
|
||||
|
||||
bool LogPage::apply()
|
||||
{
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LogPage::shouldDisplay() const
|
||||
{
|
||||
return m_instance->isRunning() || m_proxy->rowCount() > 0;
|
||||
return m_instance->isRunning() || m_proxy->rowCount() > 0;
|
||||
}
|
||||
|
||||
void LogPage::on_btnPaste_clicked()
|
||||
{
|
||||
if(!m_model)
|
||||
return;
|
||||
if(!m_model)
|
||||
return;
|
||||
|
||||
//FIXME: turn this into a proper task and move the upload logic out of GuiUtil!
|
||||
m_model->append(MessageLevel::MultiMC, tr("MultiMC: Log upload triggered at: %1").arg(QDateTime::currentDateTime().toString(Qt::RFC2822Date)));
|
||||
auto url = GuiUtil::uploadPaste(m_model->toPlainText(), this);
|
||||
if(!url.isEmpty())
|
||||
{
|
||||
m_model->append(MessageLevel::MultiMC, tr("MultiMC: Log uploaded to: %1").arg(url));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_model->append(MessageLevel::Error, tr("MultiMC: Log upload failed!"));
|
||||
}
|
||||
//FIXME: turn this into a proper task and move the upload logic out of GuiUtil!
|
||||
m_model->append(MessageLevel::MultiMC, tr("MultiMC: Log upload triggered at: %1").arg(QDateTime::currentDateTime().toString(Qt::RFC2822Date)));
|
||||
auto url = GuiUtil::uploadPaste(m_model->toPlainText(), this);
|
||||
if(!url.isEmpty())
|
||||
{
|
||||
m_model->append(MessageLevel::MultiMC, tr("MultiMC: Log uploaded to: %1").arg(url));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_model->append(MessageLevel::Error, tr("MultiMC: Log upload failed!"));
|
||||
}
|
||||
}
|
||||
|
||||
void LogPage::on_btnCopy_clicked()
|
||||
{
|
||||
if(!m_model)
|
||||
return;
|
||||
m_model->append(MessageLevel::MultiMC, QString("Clipboard copy at: %1").arg(QDateTime::currentDateTime().toString(Qt::RFC2822Date)));
|
||||
GuiUtil::setClipboardText(m_model->toPlainText());
|
||||
if(!m_model)
|
||||
return;
|
||||
m_model->append(MessageLevel::MultiMC, QString("Clipboard copy at: %1").arg(QDateTime::currentDateTime().toString(Qt::RFC2822Date)));
|
||||
GuiUtil::setClipboardText(m_model->toPlainText());
|
||||
}
|
||||
|
||||
void LogPage::on_btnClear_clicked()
|
||||
{
|
||||
if(!m_model)
|
||||
return;
|
||||
m_model->clear();
|
||||
m_container->refreshContainer();
|
||||
if(!m_model)
|
||||
return;
|
||||
m_model->clear();
|
||||
m_container->refreshContainer();
|
||||
}
|
||||
|
||||
void LogPage::on_btnBottom_clicked()
|
||||
{
|
||||
ui->text->scrollToBottom();
|
||||
ui->text->scrollToBottom();
|
||||
}
|
||||
|
||||
void LogPage::on_trackLogCheckbox_clicked(bool checked)
|
||||
{
|
||||
if(!m_model)
|
||||
return;
|
||||
m_model->suspend(!checked);
|
||||
if(!m_model)
|
||||
return;
|
||||
m_model->suspend(!checked);
|
||||
}
|
||||
|
||||
void LogPage::on_wrapCheckbox_clicked(bool checked)
|
||||
{
|
||||
ui->text->setWordWrap(checked);
|
||||
if(!m_model)
|
||||
return;
|
||||
m_model->setLineWrap(checked);
|
||||
ui->text->setWordWrap(checked);
|
||||
if(!m_model)
|
||||
return;
|
||||
m_model->setLineWrap(checked);
|
||||
}
|
||||
|
||||
void LogPage::on_findButton_clicked()
|
||||
{
|
||||
auto modifiers = QApplication::keyboardModifiers();
|
||||
bool reverse = modifiers & Qt::ShiftModifier;
|
||||
ui->text->findNext(ui->searchBar->text(), reverse);
|
||||
auto modifiers = QApplication::keyboardModifiers();
|
||||
bool reverse = modifiers & Qt::ShiftModifier;
|
||||
ui->text->findNext(ui->searchBar->text(), reverse);
|
||||
}
|
||||
|
||||
void LogPage::findNextActivated()
|
||||
{
|
||||
ui->text->findNext(ui->searchBar->text(), false);
|
||||
ui->text->findNext(ui->searchBar->text(), false);
|
||||
}
|
||||
|
||||
void LogPage::findPreviousActivated()
|
||||
{
|
||||
ui->text->findNext(ui->searchBar->text(), true);
|
||||
ui->text->findNext(ui->searchBar->text(), true);
|
||||
}
|
||||
|
||||
void LogPage::findActivated()
|
||||
{
|
||||
// focus the search bar if it doesn't have focus
|
||||
if (!ui->searchBar->hasFocus())
|
||||
{
|
||||
ui->searchBar->setFocus();
|
||||
ui->searchBar->selectAll();
|
||||
}
|
||||
// focus the search bar if it doesn't have focus
|
||||
if (!ui->searchBar->hasFocus())
|
||||
{
|
||||
ui->searchBar->setFocus();
|
||||
ui->searchBar->selectAll();
|
||||
}
|
||||
}
|
||||
|
@ -31,56 +31,56 @@ class LogFormatProxyModel;
|
||||
|
||||
class LogPage : public QWidget, public BasePage
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
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 MMC->getThemedIcon("log");
|
||||
}
|
||||
virtual QString id() const override
|
||||
{
|
||||
return "console";
|
||||
}
|
||||
virtual bool apply() override;
|
||||
virtual QString helpPage() const override
|
||||
{
|
||||
return "Minecraft-Logs";
|
||||
}
|
||||
virtual bool shouldDisplay() const override;
|
||||
explicit LogPage(InstancePtr instance, QWidget *parent = 0);
|
||||
virtual ~LogPage();
|
||||
virtual QString displayName() const override
|
||||
{
|
||||
return tr("Minecraft Log");
|
||||
}
|
||||
virtual QIcon icon() const override
|
||||
{
|
||||
return MMC->getThemedIcon("log");
|
||||
}
|
||||
virtual QString id() const override
|
||||
{
|
||||
return "console";
|
||||
}
|
||||
virtual bool apply() override;
|
||||
virtual QString helpPage() const override
|
||||
{
|
||||
return "Minecraft-Logs";
|
||||
}
|
||||
virtual bool shouldDisplay() const override;
|
||||
|
||||
private slots:
|
||||
void on_btnPaste_clicked();
|
||||
void on_btnCopy_clicked();
|
||||
void on_btnClear_clicked();
|
||||
void on_btnBottom_clicked();
|
||||
void on_btnPaste_clicked();
|
||||
void on_btnCopy_clicked();
|
||||
void on_btnClear_clicked();
|
||||
void on_btnBottom_clicked();
|
||||
|
||||
void on_trackLogCheckbox_clicked(bool checked);
|
||||
void on_wrapCheckbox_clicked(bool checked);
|
||||
void on_trackLogCheckbox_clicked(bool checked);
|
||||
void on_wrapCheckbox_clicked(bool checked);
|
||||
|
||||
void on_findButton_clicked();
|
||||
void findActivated();
|
||||
void findNextActivated();
|
||||
void findPreviousActivated();
|
||||
void on_findButton_clicked();
|
||||
void findActivated();
|
||||
void findNextActivated();
|
||||
void findPreviousActivated();
|
||||
|
||||
void onInstanceLaunchTaskChanged(std::shared_ptr<LaunchTask> proc);
|
||||
void onInstanceLaunchTaskChanged(std::shared_ptr<LaunchTask> proc);
|
||||
|
||||
private:
|
||||
void modelStateToUI();
|
||||
void UIToModelState();
|
||||
void setInstanceLaunchTaskChanged(std::shared_ptr<LaunchTask> proc, bool initial);
|
||||
void modelStateToUI();
|
||||
void UIToModelState();
|
||||
void setInstanceLaunchTaskChanged(std::shared_ptr<LaunchTask> proc, bool initial);
|
||||
|
||||
private:
|
||||
Ui::LogPage *ui;
|
||||
InstancePtr m_instance;
|
||||
std::shared_ptr<LaunchTask> m_process;
|
||||
Ui::LogPage *ui;
|
||||
InstancePtr m_instance;
|
||||
std::shared_ptr<LaunchTask> m_process;
|
||||
|
||||
LogFormatProxyModel * m_proxy;
|
||||
shared_qobject_ptr <LogModel> m_model;
|
||||
LogFormatProxyModel * m_proxy;
|
||||
shared_qobject_ptr <LogModel> m_model;
|
||||
};
|
||||
|
@ -32,179 +32,179 @@
|
||||
#include <DesktopServices.h>
|
||||
|
||||
ModFolderPage::ModFolderPage(BaseInstance *inst, std::shared_ptr<SimpleModList> mods, QString id,
|
||||
QString iconName, QString displayName, QString helpPage,
|
||||
QWidget *parent)
|
||||
: QWidget(parent), ui(new Ui::ModFolderPage)
|
||||
QString iconName, QString displayName, QString helpPage,
|
||||
QWidget *parent)
|
||||
: QWidget(parent), ui(new Ui::ModFolderPage)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->tabWidget->tabBar()->hide();
|
||||
m_inst = inst;
|
||||
m_mods = mods;
|
||||
m_id = id;
|
||||
m_displayName = displayName;
|
||||
m_iconName = iconName;
|
||||
m_helpName = helpPage;
|
||||
m_fileSelectionFilter = "%1 (*.zip *.jar)";
|
||||
m_filterModel = new QSortFilterProxyModel(this);
|
||||
m_filterModel->setDynamicSortFilter(true);
|
||||
m_filterModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
|
||||
m_filterModel->setSortCaseSensitivity(Qt::CaseInsensitive);
|
||||
m_filterModel->setSourceModel(m_mods.get());
|
||||
m_filterModel->setFilterKeyColumn(-1);
|
||||
ui->modTreeView->setModel(m_filterModel);
|
||||
ui->modTreeView->installEventFilter(this);
|
||||
ui->modTreeView->sortByColumn(1, Qt::AscendingOrder);
|
||||
auto smodel = ui->modTreeView->selectionModel();
|
||||
connect(smodel, &QItemSelectionModel::currentChanged, this, &ModFolderPage::modCurrent);
|
||||
connect(ui->filterEdit, &QLineEdit::textChanged, this, &ModFolderPage::on_filterTextChanged );
|
||||
ui->setupUi(this);
|
||||
ui->tabWidget->tabBar()->hide();
|
||||
m_inst = inst;
|
||||
m_mods = mods;
|
||||
m_id = id;
|
||||
m_displayName = displayName;
|
||||
m_iconName = iconName;
|
||||
m_helpName = helpPage;
|
||||
m_fileSelectionFilter = "%1 (*.zip *.jar)";
|
||||
m_filterModel = new QSortFilterProxyModel(this);
|
||||
m_filterModel->setDynamicSortFilter(true);
|
||||
m_filterModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
|
||||
m_filterModel->setSortCaseSensitivity(Qt::CaseInsensitive);
|
||||
m_filterModel->setSourceModel(m_mods.get());
|
||||
m_filterModel->setFilterKeyColumn(-1);
|
||||
ui->modTreeView->setModel(m_filterModel);
|
||||
ui->modTreeView->installEventFilter(this);
|
||||
ui->modTreeView->sortByColumn(1, Qt::AscendingOrder);
|
||||
auto smodel = ui->modTreeView->selectionModel();
|
||||
connect(smodel, &QItemSelectionModel::currentChanged, this, &ModFolderPage::modCurrent);
|
||||
connect(ui->filterEdit, &QLineEdit::textChanged, this, &ModFolderPage::on_filterTextChanged );
|
||||
}
|
||||
|
||||
void ModFolderPage::openedImpl()
|
||||
{
|
||||
m_mods->startWatching();
|
||||
m_mods->startWatching();
|
||||
}
|
||||
|
||||
void ModFolderPage::closedImpl()
|
||||
{
|
||||
m_mods->stopWatching();
|
||||
m_mods->stopWatching();
|
||||
}
|
||||
|
||||
void ModFolderPage::on_filterTextChanged(const QString& newContents)
|
||||
{
|
||||
m_viewFilter = newContents;
|
||||
m_filterModel->setFilterFixedString(m_viewFilter);
|
||||
m_viewFilter = newContents;
|
||||
m_filterModel->setFilterFixedString(m_viewFilter);
|
||||
}
|
||||
|
||||
|
||||
CoreModFolderPage::CoreModFolderPage(BaseInstance *inst, std::shared_ptr<SimpleModList> mods,
|
||||
QString id, QString iconName, QString displayName,
|
||||
QString helpPage, QWidget *parent)
|
||||
: ModFolderPage(inst, mods, id, iconName, displayName, helpPage, parent)
|
||||
QString id, QString iconName, QString displayName,
|
||||
QString helpPage, QWidget *parent)
|
||||
: ModFolderPage(inst, mods, id, iconName, displayName, helpPage, parent)
|
||||
{
|
||||
}
|
||||
|
||||
ModFolderPage::~ModFolderPage()
|
||||
{
|
||||
m_mods->stopWatching();
|
||||
delete ui;
|
||||
m_mods->stopWatching();
|
||||
delete ui;
|
||||
}
|
||||
|
||||
bool ModFolderPage::shouldDisplay() const
|
||||
{
|
||||
if (m_inst)
|
||||
return !m_inst->isRunning();
|
||||
return true;
|
||||
if (m_inst)
|
||||
return !m_inst->isRunning();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CoreModFolderPage::shouldDisplay() const
|
||||
{
|
||||
if (ModFolderPage::shouldDisplay())
|
||||
{
|
||||
auto inst = dynamic_cast<MinecraftInstance *>(m_inst);
|
||||
if (!inst)
|
||||
return true;
|
||||
auto version = inst->getComponentList();
|
||||
if (!version)
|
||||
return true;
|
||||
if(!version->getComponent("net.minecraftforge"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if(!version->getComponent("net.minecraft"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if(version->getComponent("net.minecraft")->getReleaseDateTime() < g_VersionFilterData.legacyCutoffDate)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
if (ModFolderPage::shouldDisplay())
|
||||
{
|
||||
auto inst = dynamic_cast<MinecraftInstance *>(m_inst);
|
||||
if (!inst)
|
||||
return true;
|
||||
auto version = inst->getComponentList();
|
||||
if (!version)
|
||||
return true;
|
||||
if(!version->getComponent("net.minecraftforge"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if(!version->getComponent("net.minecraft"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if(version->getComponent("net.minecraft")->getReleaseDateTime() < g_VersionFilterData.legacyCutoffDate)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ModFolderPage::modListFilter(QKeyEvent *keyEvent)
|
||||
{
|
||||
switch (keyEvent->key())
|
||||
{
|
||||
case Qt::Key_Delete:
|
||||
on_rmModBtn_clicked();
|
||||
return true;
|
||||
case Qt::Key_Plus:
|
||||
on_addModBtn_clicked();
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return QWidget::eventFilter(ui->modTreeView, keyEvent);
|
||||
switch (keyEvent->key())
|
||||
{
|
||||
case Qt::Key_Delete:
|
||||
on_rmModBtn_clicked();
|
||||
return true;
|
||||
case Qt::Key_Plus:
|
||||
on_addModBtn_clicked();
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return QWidget::eventFilter(ui->modTreeView, keyEvent);
|
||||
}
|
||||
|
||||
bool ModFolderPage::eventFilter(QObject *obj, QEvent *ev)
|
||||
{
|
||||
if (ev->type() != QEvent::KeyPress)
|
||||
{
|
||||
return QWidget::eventFilter(obj, ev);
|
||||
}
|
||||
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(ev);
|
||||
if (obj == ui->modTreeView)
|
||||
return modListFilter(keyEvent);
|
||||
return QWidget::eventFilter(obj, ev);
|
||||
if (ev->type() != QEvent::KeyPress)
|
||||
{
|
||||
return QWidget::eventFilter(obj, ev);
|
||||
}
|
||||
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(ev);
|
||||
if (obj == ui->modTreeView)
|
||||
return modListFilter(keyEvent);
|
||||
return QWidget::eventFilter(obj, ev);
|
||||
}
|
||||
|
||||
void ModFolderPage::on_addModBtn_clicked()
|
||||
{
|
||||
auto list = GuiUtil::BrowseForFiles(
|
||||
m_helpName,
|
||||
tr("Select %1",
|
||||
"Select whatever type of files the page contains. Example: 'Loader Mods'")
|
||||
.arg(m_displayName),
|
||||
m_fileSelectionFilter.arg(m_displayName), MMC->settings()->get("CentralModsDir").toString(),
|
||||
this->parentWidget());
|
||||
if (!list.empty())
|
||||
{
|
||||
for (auto filename : list)
|
||||
{
|
||||
m_mods->installMod(filename);
|
||||
}
|
||||
}
|
||||
auto list = GuiUtil::BrowseForFiles(
|
||||
m_helpName,
|
||||
tr("Select %1",
|
||||
"Select whatever type of files the page contains. Example: 'Loader Mods'")
|
||||
.arg(m_displayName),
|
||||
m_fileSelectionFilter.arg(m_displayName), MMC->settings()->get("CentralModsDir").toString(),
|
||||
this->parentWidget());
|
||||
if (!list.empty())
|
||||
{
|
||||
for (auto filename : list)
|
||||
{
|
||||
m_mods->installMod(filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ModFolderPage::on_enableModBtn_clicked()
|
||||
{
|
||||
auto selection = m_filterModel->mapSelectionToSource(ui->modTreeView->selectionModel()->selection());
|
||||
m_mods->enableMods(selection.indexes(), true);
|
||||
auto selection = m_filterModel->mapSelectionToSource(ui->modTreeView->selectionModel()->selection());
|
||||
m_mods->enableMods(selection.indexes(), true);
|
||||
}
|
||||
|
||||
void ModFolderPage::on_disableModBtn_clicked()
|
||||
{
|
||||
auto selection = m_filterModel->mapSelectionToSource(ui->modTreeView->selectionModel()->selection());
|
||||
m_mods->enableMods(selection.indexes(), false);
|
||||
auto selection = m_filterModel->mapSelectionToSource(ui->modTreeView->selectionModel()->selection());
|
||||
m_mods->enableMods(selection.indexes(), false);
|
||||
}
|
||||
|
||||
void ModFolderPage::on_rmModBtn_clicked()
|
||||
{
|
||||
auto selection = m_filterModel->mapSelectionToSource(ui->modTreeView->selectionModel()->selection());
|
||||
m_mods->deleteMods(selection.indexes());
|
||||
auto selection = m_filterModel->mapSelectionToSource(ui->modTreeView->selectionModel()->selection());
|
||||
m_mods->deleteMods(selection.indexes());
|
||||
}
|
||||
|
||||
void ModFolderPage::on_configFolderBtn_clicked()
|
||||
{
|
||||
DesktopServices::openDirectory(m_inst->instanceConfigFolder(), true);
|
||||
DesktopServices::openDirectory(m_inst->instanceConfigFolder(), true);
|
||||
}
|
||||
|
||||
void ModFolderPage::on_viewModBtn_clicked()
|
||||
{
|
||||
DesktopServices::openDirectory(m_mods->dir().absolutePath(), true);
|
||||
DesktopServices::openDirectory(m_mods->dir().absolutePath(), true);
|
||||
}
|
||||
|
||||
void ModFolderPage::modCurrent(const QModelIndex ¤t, const QModelIndex &previous)
|
||||
{
|
||||
if (!current.isValid())
|
||||
{
|
||||
ui->frame->clear();
|
||||
return;
|
||||
}
|
||||
auto sourceCurrent = m_filterModel->mapToSource(current);
|
||||
int row = sourceCurrent.row();
|
||||
Mod &m = m_mods->operator[](row);
|
||||
ui->frame->updateWithMod(m);
|
||||
if (!current.isValid())
|
||||
{
|
||||
ui->frame->clear();
|
||||
return;
|
||||
}
|
||||
auto sourceCurrent = m_filterModel->mapToSource(current);
|
||||
int row = sourceCurrent.row();
|
||||
Mod &m = m_mods->operator[](row);
|
||||
ui->frame->updateWithMod(m);
|
||||
}
|
||||
|
@ -29,80 +29,80 @@ class ModFolderPage;
|
||||
|
||||
class ModFolderPage : public QWidget, public BasePage
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ModFolderPage(BaseInstance *inst, std::shared_ptr<SimpleModList> mods, QString id,
|
||||
QString iconName, QString displayName, QString helpPage = "",
|
||||
QWidget *parent = 0);
|
||||
virtual ~ModFolderPage();
|
||||
explicit ModFolderPage(BaseInstance *inst, std::shared_ptr<SimpleModList> mods, QString id,
|
||||
QString iconName, QString displayName, QString helpPage = "",
|
||||
QWidget *parent = 0);
|
||||
virtual ~ModFolderPage();
|
||||
|
||||
void setFilter(const QString & filter)
|
||||
{
|
||||
m_fileSelectionFilter = filter;
|
||||
}
|
||||
void setFilter(const QString & filter)
|
||||
{
|
||||
m_fileSelectionFilter = filter;
|
||||
}
|
||||
|
||||
virtual QString displayName() const override
|
||||
{
|
||||
return m_displayName;
|
||||
}
|
||||
virtual QIcon icon() const override
|
||||
{
|
||||
return MMC->getThemedIcon(m_iconName);
|
||||
}
|
||||
virtual QString id() const override
|
||||
{
|
||||
return m_id;
|
||||
}
|
||||
virtual QString helpPage() const override
|
||||
{
|
||||
return m_helpName;
|
||||
}
|
||||
virtual bool shouldDisplay() const override;
|
||||
virtual QString displayName() const override
|
||||
{
|
||||
return m_displayName;
|
||||
}
|
||||
virtual QIcon icon() const override
|
||||
{
|
||||
return MMC->getThemedIcon(m_iconName);
|
||||
}
|
||||
virtual QString id() const override
|
||||
{
|
||||
return m_id;
|
||||
}
|
||||
virtual QString helpPage() const override
|
||||
{
|
||||
return m_helpName;
|
||||
}
|
||||
virtual bool shouldDisplay() const override;
|
||||
|
||||
virtual void openedImpl() override;
|
||||
virtual void closedImpl() override;
|
||||
virtual void openedImpl() override;
|
||||
virtual void closedImpl() override;
|
||||
protected:
|
||||
bool eventFilter(QObject *obj, QEvent *ev) override;
|
||||
bool modListFilter(QKeyEvent *ev);
|
||||
bool eventFilter(QObject *obj, QEvent *ev) override;
|
||||
bool modListFilter(QKeyEvent *ev);
|
||||
|
||||
protected:
|
||||
BaseInstance *m_inst;
|
||||
BaseInstance *m_inst;
|
||||
|
||||
protected:
|
||||
Ui::ModFolderPage *ui;
|
||||
std::shared_ptr<SimpleModList> m_mods;
|
||||
QSortFilterProxyModel *m_filterModel;
|
||||
QString m_iconName;
|
||||
QString m_id;
|
||||
QString m_displayName;
|
||||
QString m_helpName;
|
||||
QString m_fileSelectionFilter;
|
||||
QString m_viewFilter;
|
||||
Ui::ModFolderPage *ui;
|
||||
std::shared_ptr<SimpleModList> m_mods;
|
||||
QSortFilterProxyModel *m_filterModel;
|
||||
QString m_iconName;
|
||||
QString m_id;
|
||||
QString m_displayName;
|
||||
QString m_helpName;
|
||||
QString m_fileSelectionFilter;
|
||||
QString m_viewFilter;
|
||||
|
||||
public
|
||||
slots:
|
||||
void modCurrent(const QModelIndex ¤t, const QModelIndex &previous);
|
||||
void modCurrent(const QModelIndex ¤t, const QModelIndex &previous);
|
||||
|
||||
private
|
||||
slots:
|
||||
void on_filterTextChanged(const QString & newContents);
|
||||
void on_addModBtn_clicked();
|
||||
void on_rmModBtn_clicked();
|
||||
void on_viewModBtn_clicked();
|
||||
void on_enableModBtn_clicked();
|
||||
void on_disableModBtn_clicked();
|
||||
void on_configFolderBtn_clicked();
|
||||
void on_filterTextChanged(const QString & newContents);
|
||||
void on_addModBtn_clicked();
|
||||
void on_rmModBtn_clicked();
|
||||
void on_viewModBtn_clicked();
|
||||
void on_enableModBtn_clicked();
|
||||
void on_disableModBtn_clicked();
|
||||
void on_configFolderBtn_clicked();
|
||||
};
|
||||
|
||||
class CoreModFolderPage : public ModFolderPage
|
||||
{
|
||||
public:
|
||||
explicit CoreModFolderPage(BaseInstance *inst, std::shared_ptr<SimpleModList> mods, QString id,
|
||||
QString iconName, QString displayName, QString helpPage = "",
|
||||
QWidget *parent = 0);
|
||||
virtual ~CoreModFolderPage()
|
||||
{
|
||||
}
|
||||
virtual bool shouldDisplay() const;
|
||||
explicit CoreModFolderPage(BaseInstance *inst, std::shared_ptr<SimpleModList> mods, QString id,
|
||||
QString iconName, QString displayName, QString helpPage = "",
|
||||
QWidget *parent = 0);
|
||||
virtual ~CoreModFolderPage()
|
||||
{
|
||||
}
|
||||
virtual bool shouldDisplay() const;
|
||||
};
|
||||
|
@ -32,146 +32,146 @@
|
||||
#include <DesktopServices.h>
|
||||
|
||||
NewModFolderPage::NewModFolderPage(BaseInstance *inst, std::shared_ptr<ModsModel> mods, QString id,
|
||||
QString iconName, QString displayName, QString helpPage,
|
||||
QWidget *parent)
|
||||
: QWidget(parent), ui(new Ui::NewModFolderPage)
|
||||
QString iconName, QString displayName, QString helpPage,
|
||||
QWidget *parent)
|
||||
: QWidget(parent), ui(new Ui::NewModFolderPage)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->tabWidget->tabBar()->hide();
|
||||
m_inst = inst;
|
||||
m_mods = mods;
|
||||
m_id = id;
|
||||
m_displayName = displayName;
|
||||
m_iconName = iconName;
|
||||
m_helpName = helpPage;
|
||||
m_fileSelectionFilter = "%1 (*.zip *.jar)";
|
||||
m_filterModel = new QSortFilterProxyModel(this);
|
||||
m_filterModel->setDynamicSortFilter(true);
|
||||
m_filterModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
|
||||
m_filterModel->setSortCaseSensitivity(Qt::CaseInsensitive);
|
||||
m_filterModel->setSourceModel(m_mods.get());
|
||||
m_filterModel->setFilterKeyColumn(-1);
|
||||
ui->modTreeView->setModel(m_filterModel);
|
||||
ui->modTreeView->installEventFilter(this);
|
||||
ui->modTreeView->sortByColumn(1, Qt::AscendingOrder);
|
||||
auto smodel = ui->modTreeView->selectionModel();
|
||||
connect(smodel, &QItemSelectionModel::currentChanged, this, &NewModFolderPage::modCurrent);
|
||||
connect(ui->filterEdit, &QLineEdit::textChanged, this, &NewModFolderPage::on_filterTextChanged );
|
||||
ui->setupUi(this);
|
||||
ui->tabWidget->tabBar()->hide();
|
||||
m_inst = inst;
|
||||
m_mods = mods;
|
||||
m_id = id;
|
||||
m_displayName = displayName;
|
||||
m_iconName = iconName;
|
||||
m_helpName = helpPage;
|
||||
m_fileSelectionFilter = "%1 (*.zip *.jar)";
|
||||
m_filterModel = new QSortFilterProxyModel(this);
|
||||
m_filterModel->setDynamicSortFilter(true);
|
||||
m_filterModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
|
||||
m_filterModel->setSortCaseSensitivity(Qt::CaseInsensitive);
|
||||
m_filterModel->setSourceModel(m_mods.get());
|
||||
m_filterModel->setFilterKeyColumn(-1);
|
||||
ui->modTreeView->setModel(m_filterModel);
|
||||
ui->modTreeView->installEventFilter(this);
|
||||
ui->modTreeView->sortByColumn(1, Qt::AscendingOrder);
|
||||
auto smodel = ui->modTreeView->selectionModel();
|
||||
connect(smodel, &QItemSelectionModel::currentChanged, this, &NewModFolderPage::modCurrent);
|
||||
connect(ui->filterEdit, &QLineEdit::textChanged, this, &NewModFolderPage::on_filterTextChanged );
|
||||
}
|
||||
|
||||
void NewModFolderPage::openedImpl()
|
||||
{
|
||||
m_mods->startWatching();
|
||||
m_mods->startWatching();
|
||||
}
|
||||
|
||||
void NewModFolderPage::closedImpl()
|
||||
{
|
||||
m_mods->stopWatching();
|
||||
m_mods->stopWatching();
|
||||
}
|
||||
|
||||
void NewModFolderPage::on_filterTextChanged(const QString& newContents)
|
||||
{
|
||||
m_viewFilter = newContents;
|
||||
m_filterModel->setFilterFixedString(m_viewFilter);
|
||||
m_viewFilter = newContents;
|
||||
m_filterModel->setFilterFixedString(m_viewFilter);
|
||||
}
|
||||
|
||||
|
||||
NewModFolderPage::~NewModFolderPage()
|
||||
{
|
||||
m_mods->stopWatching();
|
||||
delete ui;
|
||||
m_mods->stopWatching();
|
||||
delete ui;
|
||||
}
|
||||
|
||||
bool NewModFolderPage::shouldDisplay() const
|
||||
{
|
||||
if (m_inst)
|
||||
return !m_inst->isRunning();
|
||||
return true;
|
||||
if (m_inst)
|
||||
return !m_inst->isRunning();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NewModFolderPage::modListFilter(QKeyEvent *keyEvent)
|
||||
{
|
||||
switch (keyEvent->key())
|
||||
{
|
||||
case Qt::Key_Delete:
|
||||
on_rmModBtn_clicked();
|
||||
return true;
|
||||
case Qt::Key_Plus:
|
||||
on_addModBtn_clicked();
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return QWidget::eventFilter(ui->modTreeView, keyEvent);
|
||||
switch (keyEvent->key())
|
||||
{
|
||||
case Qt::Key_Delete:
|
||||
on_rmModBtn_clicked();
|
||||
return true;
|
||||
case Qt::Key_Plus:
|
||||
on_addModBtn_clicked();
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return QWidget::eventFilter(ui->modTreeView, keyEvent);
|
||||
}
|
||||
|
||||
bool NewModFolderPage::eventFilter(QObject *obj, QEvent *ev)
|
||||
{
|
||||
if (ev->type() != QEvent::KeyPress)
|
||||
{
|
||||
return QWidget::eventFilter(obj, ev);
|
||||
}
|
||||
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(ev);
|
||||
if (obj == ui->modTreeView)
|
||||
return modListFilter(keyEvent);
|
||||
return QWidget::eventFilter(obj, ev);
|
||||
if (ev->type() != QEvent::KeyPress)
|
||||
{
|
||||
return QWidget::eventFilter(obj, ev);
|
||||
}
|
||||
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(ev);
|
||||
if (obj == ui->modTreeView)
|
||||
return modListFilter(keyEvent);
|
||||
return QWidget::eventFilter(obj, ev);
|
||||
}
|
||||
|
||||
void NewModFolderPage::on_addModBtn_clicked()
|
||||
{
|
||||
auto list = GuiUtil::BrowseForFiles(
|
||||
m_helpName,
|
||||
tr("Select %1",
|
||||
"Select whatever type of files the page contains. Example: 'Loader Mods'")
|
||||
.arg(m_displayName),
|
||||
m_fileSelectionFilter.arg(m_displayName), MMC->settings()->get("CentralModsDir").toString(),
|
||||
this->parentWidget());
|
||||
if (!list.empty())
|
||||
{
|
||||
for (auto filename : list)
|
||||
{
|
||||
m_mods->installMod(filename);
|
||||
}
|
||||
}
|
||||
auto list = GuiUtil::BrowseForFiles(
|
||||
m_helpName,
|
||||
tr("Select %1",
|
||||
"Select whatever type of files the page contains. Example: 'Loader Mods'")
|
||||
.arg(m_displayName),
|
||||
m_fileSelectionFilter.arg(m_displayName), MMC->settings()->get("CentralModsDir").toString(),
|
||||
this->parentWidget());
|
||||
if (!list.empty())
|
||||
{
|
||||
for (auto filename : list)
|
||||
{
|
||||
m_mods->installMod(filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NewModFolderPage::on_enableModBtn_clicked()
|
||||
{
|
||||
auto selection = m_filterModel->mapSelectionToSource(ui->modTreeView->selectionModel()->selection());
|
||||
m_mods->enableMods(selection.indexes(), true);
|
||||
auto selection = m_filterModel->mapSelectionToSource(ui->modTreeView->selectionModel()->selection());
|
||||
m_mods->enableMods(selection.indexes(), true);
|
||||
}
|
||||
|
||||
void NewModFolderPage::on_disableModBtn_clicked()
|
||||
{
|
||||
auto selection = m_filterModel->mapSelectionToSource(ui->modTreeView->selectionModel()->selection());
|
||||
m_mods->enableMods(selection.indexes(), false);
|
||||
auto selection = m_filterModel->mapSelectionToSource(ui->modTreeView->selectionModel()->selection());
|
||||
m_mods->enableMods(selection.indexes(), false);
|
||||
}
|
||||
|
||||
void NewModFolderPage::on_rmModBtn_clicked()
|
||||
{
|
||||
auto selection = m_filterModel->mapSelectionToSource(ui->modTreeView->selectionModel()->selection());
|
||||
m_mods->deleteMods(selection.indexes());
|
||||
auto selection = m_filterModel->mapSelectionToSource(ui->modTreeView->selectionModel()->selection());
|
||||
m_mods->deleteMods(selection.indexes());
|
||||
}
|
||||
|
||||
void NewModFolderPage::on_configFolderBtn_clicked()
|
||||
{
|
||||
DesktopServices::openDirectory(m_inst->instanceConfigFolder(), true);
|
||||
DesktopServices::openDirectory(m_inst->instanceConfigFolder(), true);
|
||||
}
|
||||
|
||||
void NewModFolderPage::on_viewModBtn_clicked()
|
||||
{
|
||||
DesktopServices::openDirectory(m_mods->dir().absolutePath(), true);
|
||||
DesktopServices::openDirectory(m_mods->dir().absolutePath(), true);
|
||||
}
|
||||
|
||||
void NewModFolderPage::modCurrent(const QModelIndex ¤t, const QModelIndex &previous)
|
||||
{
|
||||
if (!current.isValid())
|
||||
{
|
||||
ui->frame->clear();
|
||||
return;
|
||||
}
|
||||
auto sourceCurrent = m_filterModel->mapToSource(current);
|
||||
int row = sourceCurrent.row();
|
||||
Mod &m = m_mods->operator[](row);
|
||||
ui->frame->updateWithMod(m);
|
||||
if (!current.isValid())
|
||||
{
|
||||
ui->frame->clear();
|
||||
return;
|
||||
}
|
||||
auto sourceCurrent = m_filterModel->mapToSource(current);
|
||||
int row = sourceCurrent.row();
|
||||
Mod &m = m_mods->operator[](row);
|
||||
ui->frame->updateWithMod(m);
|
||||
}
|
||||
|
@ -29,69 +29,69 @@ class NewModFolderPage;
|
||||
|
||||
class NewModFolderPage : public QWidget, public BasePage
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit NewModFolderPage(BaseInstance *inst, std::shared_ptr<ModsModel> mods, QString id,
|
||||
QString iconName, QString displayName, QString helpPage = "",
|
||||
QWidget *parent = 0);
|
||||
virtual ~NewModFolderPage();
|
||||
explicit NewModFolderPage(BaseInstance *inst, std::shared_ptr<ModsModel> mods, QString id,
|
||||
QString iconName, QString displayName, QString helpPage = "",
|
||||
QWidget *parent = 0);
|
||||
virtual ~NewModFolderPage();
|
||||
|
||||
void setFilter(const QString & filter)
|
||||
{
|
||||
m_fileSelectionFilter = filter;
|
||||
}
|
||||
void setFilter(const QString & filter)
|
||||
{
|
||||
m_fileSelectionFilter = filter;
|
||||
}
|
||||
|
||||
virtual QString displayName() const override
|
||||
{
|
||||
return m_displayName;
|
||||
}
|
||||
virtual QIcon icon() const override
|
||||
{
|
||||
return MMC->getThemedIcon(m_iconName);
|
||||
}
|
||||
virtual QString id() const override
|
||||
{
|
||||
return m_id;
|
||||
}
|
||||
virtual QString helpPage() const override
|
||||
{
|
||||
return m_helpName;
|
||||
}
|
||||
virtual bool shouldDisplay() const override;
|
||||
virtual QString displayName() const override
|
||||
{
|
||||
return m_displayName;
|
||||
}
|
||||
virtual QIcon icon() const override
|
||||
{
|
||||
return MMC->getThemedIcon(m_iconName);
|
||||
}
|
||||
virtual QString id() const override
|
||||
{
|
||||
return m_id;
|
||||
}
|
||||
virtual QString helpPage() const override
|
||||
{
|
||||
return m_helpName;
|
||||
}
|
||||
virtual bool shouldDisplay() const override;
|
||||
|
||||
virtual void openedImpl() override;
|
||||
virtual void closedImpl() override;
|
||||
virtual void openedImpl() override;
|
||||
virtual void closedImpl() override;
|
||||
protected:
|
||||
bool eventFilter(QObject *obj, QEvent *ev) override;
|
||||
bool modListFilter(QKeyEvent *ev);
|
||||
bool eventFilter(QObject *obj, QEvent *ev) override;
|
||||
bool modListFilter(QKeyEvent *ev);
|
||||
|
||||
protected:
|
||||
BaseInstance *m_inst;
|
||||
BaseInstance *m_inst;
|
||||
|
||||
protected:
|
||||
Ui::NewModFolderPage *ui;
|
||||
std::shared_ptr<ModsModel> m_mods;
|
||||
QSortFilterProxyModel *m_filterModel;
|
||||
QString m_iconName;
|
||||
QString m_id;
|
||||
QString m_displayName;
|
||||
QString m_helpName;
|
||||
QString m_fileSelectionFilter;
|
||||
QString m_viewFilter;
|
||||
Ui::NewModFolderPage *ui;
|
||||
std::shared_ptr<ModsModel> m_mods;
|
||||
QSortFilterProxyModel *m_filterModel;
|
||||
QString m_iconName;
|
||||
QString m_id;
|
||||
QString m_displayName;
|
||||
QString m_helpName;
|
||||
QString m_fileSelectionFilter;
|
||||
QString m_viewFilter;
|
||||
|
||||
public
|
||||
slots:
|
||||
void modCurrent(const QModelIndex ¤t, const QModelIndex &previous);
|
||||
void modCurrent(const QModelIndex ¤t, const QModelIndex &previous);
|
||||
|
||||
private
|
||||
slots:
|
||||
void on_filterTextChanged(const QString & newContents);
|
||||
void on_addModBtn_clicked();
|
||||
void on_rmModBtn_clicked();
|
||||
void on_viewModBtn_clicked();
|
||||
void on_enableModBtn_clicked();
|
||||
void on_disableModBtn_clicked();
|
||||
void on_configFolderBtn_clicked();
|
||||
void on_filterTextChanged(const QString & newContents);
|
||||
void on_addModBtn_clicked();
|
||||
void on_rmModBtn_clicked();
|
||||
void on_viewModBtn_clicked();
|
||||
void on_enableModBtn_clicked();
|
||||
void on_disableModBtn_clicked();
|
||||
void on_configFolderBtn_clicked();
|
||||
};
|
||||
|
||||
|
@ -3,20 +3,20 @@
|
||||
#include <QTabBar>
|
||||
|
||||
NotesPage::NotesPage(BaseInstance *inst, QWidget *parent)
|
||||
: QWidget(parent), ui(new Ui::NotesPage), m_inst(inst)
|
||||
: QWidget(parent), ui(new Ui::NotesPage), m_inst(inst)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->tabWidget->tabBar()->hide();
|
||||
ui->noteEditor->setText(m_inst->notes());
|
||||
ui->setupUi(this);
|
||||
ui->tabWidget->tabBar()->hide();
|
||||
ui->noteEditor->setText(m_inst->notes());
|
||||
}
|
||||
|
||||
NotesPage::~NotesPage()
|
||||
{
|
||||
delete ui;
|
||||
delete ui;
|
||||
}
|
||||
|
||||
bool NotesPage::apply()
|
||||
{
|
||||
m_inst->setNotes(ui->noteEditor->toPlainText());
|
||||
return true;
|
||||
m_inst->setNotes(ui->noteEditor->toPlainText());
|
||||
return true;
|
||||
}
|
||||
|
@ -28,33 +28,33 @@ class NotesPage;
|
||||
|
||||
class NotesPage : public QWidget, public BasePage
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit NotesPage(BaseInstance *inst, QWidget *parent = 0);
|
||||
virtual ~NotesPage();
|
||||
virtual QString displayName() const override
|
||||
{
|
||||
return tr("Notes");
|
||||
}
|
||||
virtual QIcon icon() const override
|
||||
{
|
||||
auto icon = MMC->getThemedIcon("notes");
|
||||
if(icon.isNull())
|
||||
icon = MMC->getThemedIcon("news");
|
||||
return icon;
|
||||
}
|
||||
virtual QString id() const override
|
||||
{
|
||||
return "notes";
|
||||
}
|
||||
virtual bool apply() override;
|
||||
virtual QString helpPage() const override
|
||||
{
|
||||
return "Notes";
|
||||
}
|
||||
explicit NotesPage(BaseInstance *inst, QWidget *parent = 0);
|
||||
virtual ~NotesPage();
|
||||
virtual QString displayName() const override
|
||||
{
|
||||
return tr("Notes");
|
||||
}
|
||||
virtual QIcon icon() const override
|
||||
{
|
||||
auto icon = MMC->getThemedIcon("notes");
|
||||
if(icon.isNull())
|
||||
icon = MMC->getThemedIcon("news");
|
||||
return icon;
|
||||
}
|
||||
virtual QString id() const override
|
||||
{
|
||||
return "notes";
|
||||
}
|
||||
virtual bool apply() override;
|
||||
virtual QString helpPage() const override
|
||||
{
|
||||
return "Notes";
|
||||
}
|
||||
|
||||
private:
|
||||
Ui::NotesPage *ui;
|
||||
BaseInstance *m_inst;
|
||||
Ui::NotesPage *ui;
|
||||
BaseInstance *m_inst;
|
||||
};
|
||||
|
@ -25,289 +25,289 @@
|
||||
#include <QShortcut>
|
||||
|
||||
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))
|
||||
: QWidget(parent), ui(new Ui::OtherLogsPage), m_path(path), m_fileFilter(fileFilter),
|
||||
m_watcher(new RecursiveFileSystemWatcher(this))
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->tabWidget->tabBar()->hide();
|
||||
ui->setupUi(this);
|
||||
ui->tabWidget->tabBar()->hide();
|
||||
|
||||
m_watcher->setMatcher(fileFilter);
|
||||
m_watcher->setRootDir(QDir::current().absoluteFilePath(m_path));
|
||||
m_watcher->setMatcher(fileFilter);
|
||||
m_watcher->setRootDir(QDir::current().absoluteFilePath(m_path));
|
||||
|
||||
connect(m_watcher, &RecursiveFileSystemWatcher::filesChanged, this, &OtherLogsPage::populateSelectLogBox);
|
||||
populateSelectLogBox();
|
||||
connect(m_watcher, &RecursiveFileSystemWatcher::filesChanged, this, &OtherLogsPage::populateSelectLogBox);
|
||||
populateSelectLogBox();
|
||||
|
||||
auto findShortcut = new QShortcut(QKeySequence(QKeySequence::Find), this);
|
||||
connect(findShortcut, &QShortcut::activated, this, &OtherLogsPage::findActivated);
|
||||
auto findShortcut = new QShortcut(QKeySequence(QKeySequence::Find), this);
|
||||
connect(findShortcut, &QShortcut::activated, this, &OtherLogsPage::findActivated);
|
||||
|
||||
auto findNextShortcut = new QShortcut(QKeySequence(QKeySequence::FindNext), this);
|
||||
connect(findNextShortcut, &QShortcut::activated, this, &OtherLogsPage::findNextActivated);
|
||||
auto findNextShortcut = new QShortcut(QKeySequence(QKeySequence::FindNext), this);
|
||||
connect(findNextShortcut, &QShortcut::activated, this, &OtherLogsPage::findNextActivated);
|
||||
|
||||
auto findPreviousShortcut = new QShortcut(QKeySequence(QKeySequence::FindPrevious), this);
|
||||
connect(findPreviousShortcut, &QShortcut::activated, this, &OtherLogsPage::findPreviousActivated);
|
||||
auto findPreviousShortcut = new QShortcut(QKeySequence(QKeySequence::FindPrevious), this);
|
||||
connect(findPreviousShortcut, &QShortcut::activated, this, &OtherLogsPage::findPreviousActivated);
|
||||
|
||||
connect(ui->searchBar, &QLineEdit::returnPressed, this, &OtherLogsPage::on_findButton_clicked);
|
||||
connect(ui->searchBar, &QLineEdit::returnPressed, this, &OtherLogsPage::on_findButton_clicked);
|
||||
}
|
||||
|
||||
OtherLogsPage::~OtherLogsPage()
|
||||
{
|
||||
delete ui;
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void OtherLogsPage::openedImpl()
|
||||
{
|
||||
m_watcher->enable();
|
||||
m_watcher->enable();
|
||||
}
|
||||
void OtherLogsPage::closedImpl()
|
||||
{
|
||||
m_watcher->disable();
|
||||
m_watcher->disable();
|
||||
}
|
||||
|
||||
void OtherLogsPage::populateSelectLogBox()
|
||||
{
|
||||
ui->selectLogBox->clear();
|
||||
ui->selectLogBox->addItems(m_watcher->files());
|
||||
if (m_currentFile.isEmpty())
|
||||
{
|
||||
setControlsEnabled(false);
|
||||
ui->selectLogBox->setCurrentIndex(-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
const int index = ui->selectLogBox->findText(m_currentFile);
|
||||
if (index != -1)
|
||||
{
|
||||
ui->selectLogBox->setCurrentIndex(index);
|
||||
setControlsEnabled(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
setControlsEnabled(false);
|
||||
}
|
||||
}
|
||||
ui->selectLogBox->clear();
|
||||
ui->selectLogBox->addItems(m_watcher->files());
|
||||
if (m_currentFile.isEmpty())
|
||||
{
|
||||
setControlsEnabled(false);
|
||||
ui->selectLogBox->setCurrentIndex(-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
const int index = ui->selectLogBox->findText(m_currentFile);
|
||||
if (index != -1)
|
||||
{
|
||||
ui->selectLogBox->setCurrentIndex(index);
|
||||
setControlsEnabled(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
setControlsEnabled(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OtherLogsPage::on_selectLogBox_currentIndexChanged(const int index)
|
||||
{
|
||||
QString file;
|
||||
if (index != -1)
|
||||
{
|
||||
file = ui->selectLogBox->itemText(index);
|
||||
}
|
||||
QString file;
|
||||
if (index != -1)
|
||||
{
|
||||
file = ui->selectLogBox->itemText(index);
|
||||
}
|
||||
|
||||
if (file.isEmpty() || !QFile::exists(FS::PathCombine(m_path, file)))
|
||||
{
|
||||
m_currentFile = QString();
|
||||
ui->text->clear();
|
||||
setControlsEnabled(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_currentFile = file;
|
||||
on_btnReload_clicked();
|
||||
setControlsEnabled(true);
|
||||
}
|
||||
if (file.isEmpty() || !QFile::exists(FS::PathCombine(m_path, file)))
|
||||
{
|
||||
m_currentFile = QString();
|
||||
ui->text->clear();
|
||||
setControlsEnabled(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_currentFile = file;
|
||||
on_btnReload_clicked();
|
||||
setControlsEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
void OtherLogsPage::on_btnReload_clicked()
|
||||
{
|
||||
if(m_currentFile.isEmpty())
|
||||
{
|
||||
setControlsEnabled(false);
|
||||
return;
|
||||
}
|
||||
QFile file(FS::PathCombine(m_path, m_currentFile));
|
||||
if (!file.open(QFile::ReadOnly))
|
||||
{
|
||||
setControlsEnabled(false);
|
||||
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)
|
||||
{
|
||||
QString fontFamily = MMC->settings()->get("ConsoleFont").toString();
|
||||
bool conversionOk = false;
|
||||
int fontSize = MMC->settings()->get("ConsoleFontSize").toInt(&conversionOk);
|
||||
if(!conversionOk)
|
||||
{
|
||||
fontSize = 11;
|
||||
}
|
||||
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()));
|
||||
};
|
||||
if(file.size() > (1024ll * 1024ll * 12ll))
|
||||
{
|
||||
showTooBig();
|
||||
return;
|
||||
}
|
||||
QString content;
|
||||
if(file.fileName().endsWith(".gz"))
|
||||
{
|
||||
QByteArray temp;
|
||||
if(!GZip::unzip(file.readAll(), temp))
|
||||
{
|
||||
setPlainText(
|
||||
tr("The file (%1) is not readable.").arg(file.fileName()));
|
||||
return;
|
||||
}
|
||||
content = QString::fromUtf8(temp);
|
||||
}
|
||||
else
|
||||
{
|
||||
content = QString::fromUtf8(file.readAll());
|
||||
}
|
||||
if (content.size() >= 50000000ll)
|
||||
{
|
||||
showTooBig();
|
||||
return;
|
||||
}
|
||||
setPlainText(content);
|
||||
}
|
||||
if(m_currentFile.isEmpty())
|
||||
{
|
||||
setControlsEnabled(false);
|
||||
return;
|
||||
}
|
||||
QFile file(FS::PathCombine(m_path, m_currentFile));
|
||||
if (!file.open(QFile::ReadOnly))
|
||||
{
|
||||
setControlsEnabled(false);
|
||||
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)
|
||||
{
|
||||
QString fontFamily = MMC->settings()->get("ConsoleFont").toString();
|
||||
bool conversionOk = false;
|
||||
int fontSize = MMC->settings()->get("ConsoleFontSize").toInt(&conversionOk);
|
||||
if(!conversionOk)
|
||||
{
|
||||
fontSize = 11;
|
||||
}
|
||||
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()));
|
||||
};
|
||||
if(file.size() > (1024ll * 1024ll * 12ll))
|
||||
{
|
||||
showTooBig();
|
||||
return;
|
||||
}
|
||||
QString content;
|
||||
if(file.fileName().endsWith(".gz"))
|
||||
{
|
||||
QByteArray temp;
|
||||
if(!GZip::unzip(file.readAll(), temp))
|
||||
{
|
||||
setPlainText(
|
||||
tr("The file (%1) is not readable.").arg(file.fileName()));
|
||||
return;
|
||||
}
|
||||
content = QString::fromUtf8(temp);
|
||||
}
|
||||
else
|
||||
{
|
||||
content = QString::fromUtf8(file.readAll());
|
||||
}
|
||||
if (content.size() >= 50000000ll)
|
||||
{
|
||||
showTooBig();
|
||||
return;
|
||||
}
|
||||
setPlainText(content);
|
||||
}
|
||||
}
|
||||
|
||||
void OtherLogsPage::on_btnPaste_clicked()
|
||||
{
|
||||
GuiUtil::uploadPaste(ui->text->toPlainText(), this);
|
||||
GuiUtil::uploadPaste(ui->text->toPlainText(), this);
|
||||
}
|
||||
|
||||
void OtherLogsPage::on_btnCopy_clicked()
|
||||
{
|
||||
GuiUtil::setClipboardText(ui->text->toPlainText());
|
||||
GuiUtil::setClipboardText(ui->text->toPlainText());
|
||||
}
|
||||
|
||||
void OtherLogsPage::on_btnDelete_clicked()
|
||||
{
|
||||
if(m_currentFile.isEmpty())
|
||||
{
|
||||
setControlsEnabled(false);
|
||||
return;
|
||||
}
|
||||
if (QMessageBox::question(this, tr("Delete"),
|
||||
tr("Do you really want to delete %1?").arg(m_currentFile),
|
||||
QMessageBox::Yes, QMessageBox::No) == QMessageBox::No)
|
||||
{
|
||||
return;
|
||||
}
|
||||
QFile file(FS::PathCombine(m_path, m_currentFile));
|
||||
if (!file.remove())
|
||||
{
|
||||
QMessageBox::critical(this, tr("Error"), tr("Unable to delete %1: %2")
|
||||
.arg(m_currentFile, file.errorString()));
|
||||
}
|
||||
if(m_currentFile.isEmpty())
|
||||
{
|
||||
setControlsEnabled(false);
|
||||
return;
|
||||
}
|
||||
if (QMessageBox::question(this, tr("Delete"),
|
||||
tr("Do you really want to delete %1?").arg(m_currentFile),
|
||||
QMessageBox::Yes, QMessageBox::No) == QMessageBox::No)
|
||||
{
|
||||
return;
|
||||
}
|
||||
QFile file(FS::PathCombine(m_path, m_currentFile));
|
||||
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())
|
||||
{
|
||||
return;
|
||||
}
|
||||
QMessageBox *messageBox = new QMessageBox(this);
|
||||
messageBox->setWindowTitle(tr("Clean up"));
|
||||
if(toDelete.size() > 5)
|
||||
{
|
||||
messageBox->setText(tr("Do you really want to delete all log files?"));
|
||||
messageBox->setDetailedText(toDelete.join('\n'));
|
||||
}
|
||||
else
|
||||
{
|
||||
messageBox->setText(tr("Do you really want to delete these files?\n%1").arg(toDelete.join('\n')));
|
||||
}
|
||||
messageBox->setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
|
||||
messageBox->setDefaultButton(QMessageBox::Ok);
|
||||
messageBox->setTextInteractionFlags(Qt::TextSelectableByMouse);
|
||||
messageBox->setIcon(QMessageBox::Question);
|
||||
messageBox->setTextInteractionFlags(Qt::TextBrowserInteraction);
|
||||
auto toDelete = m_watcher->files();
|
||||
if(toDelete.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
QMessageBox *messageBox = new QMessageBox(this);
|
||||
messageBox->setWindowTitle(tr("Clean up"));
|
||||
if(toDelete.size() > 5)
|
||||
{
|
||||
messageBox->setText(tr("Do you really want to delete all log files?"));
|
||||
messageBox->setDetailedText(toDelete.join('\n'));
|
||||
}
|
||||
else
|
||||
{
|
||||
messageBox->setText(tr("Do you really want to delete these files?\n%1").arg(toDelete.join('\n')));
|
||||
}
|
||||
messageBox->setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
|
||||
messageBox->setDefaultButton(QMessageBox::Ok);
|
||||
messageBox->setTextInteractionFlags(Qt::TextSelectableByMouse);
|
||||
messageBox->setIcon(QMessageBox::Question);
|
||||
messageBox->setTextInteractionFlags(Qt::TextBrowserInteraction);
|
||||
|
||||
if (messageBox->exec() != QMessageBox::Ok)
|
||||
{
|
||||
return;
|
||||
}
|
||||
QStringList failed;
|
||||
for(auto item: toDelete)
|
||||
{
|
||||
QFile file(FS::PathCombine(m_path, item));
|
||||
if (!file.remove())
|
||||
{
|
||||
failed.push_back(item);
|
||||
}
|
||||
}
|
||||
if(!failed.empty())
|
||||
{
|
||||
QMessageBox *messageBox = new QMessageBox(this);
|
||||
messageBox->setWindowTitle(tr("Error"));
|
||||
if(failed.size() > 5)
|
||||
{
|
||||
messageBox->setText(tr("Couldn't delete some files!"));
|
||||
messageBox->setDetailedText(failed.join('\n'));
|
||||
}
|
||||
else
|
||||
{
|
||||
messageBox->setText(tr("Couldn't delete some files:\n%1").arg(failed.join('\n')));
|
||||
}
|
||||
messageBox->setStandardButtons(QMessageBox::Ok);
|
||||
messageBox->setDefaultButton(QMessageBox::Ok);
|
||||
messageBox->setTextInteractionFlags(Qt::TextSelectableByMouse);
|
||||
messageBox->setIcon(QMessageBox::Critical);
|
||||
messageBox->setTextInteractionFlags(Qt::TextBrowserInteraction);
|
||||
messageBox->exec();
|
||||
}
|
||||
if (messageBox->exec() != QMessageBox::Ok)
|
||||
{
|
||||
return;
|
||||
}
|
||||
QStringList failed;
|
||||
for(auto item: toDelete)
|
||||
{
|
||||
QFile file(FS::PathCombine(m_path, item));
|
||||
if (!file.remove())
|
||||
{
|
||||
failed.push_back(item);
|
||||
}
|
||||
}
|
||||
if(!failed.empty())
|
||||
{
|
||||
QMessageBox *messageBox = new QMessageBox(this);
|
||||
messageBox->setWindowTitle(tr("Error"));
|
||||
if(failed.size() > 5)
|
||||
{
|
||||
messageBox->setText(tr("Couldn't delete some files!"));
|
||||
messageBox->setDetailedText(failed.join('\n'));
|
||||
}
|
||||
else
|
||||
{
|
||||
messageBox->setText(tr("Couldn't delete some files:\n%1").arg(failed.join('\n')));
|
||||
}
|
||||
messageBox->setStandardButtons(QMessageBox::Ok);
|
||||
messageBox->setDefaultButton(QMessageBox::Ok);
|
||||
messageBox->setTextInteractionFlags(Qt::TextSelectableByMouse);
|
||||
messageBox->setIcon(QMessageBox::Critical);
|
||||
messageBox->setTextInteractionFlags(Qt::TextBrowserInteraction);
|
||||
messageBox->exec();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void OtherLogsPage::setControlsEnabled(const bool enabled)
|
||||
{
|
||||
ui->btnReload->setEnabled(enabled);
|
||||
ui->btnDelete->setEnabled(enabled);
|
||||
ui->btnCopy->setEnabled(enabled);
|
||||
ui->btnPaste->setEnabled(enabled);
|
||||
ui->text->setEnabled(enabled);
|
||||
ui->btnClean->setEnabled(enabled);
|
||||
ui->btnReload->setEnabled(enabled);
|
||||
ui->btnDelete->setEnabled(enabled);
|
||||
ui->btnCopy->setEnabled(enabled);
|
||||
ui->btnPaste->setEnabled(enabled);
|
||||
ui->text->setEnabled(enabled);
|
||||
ui->btnClean->setEnabled(enabled);
|
||||
}
|
||||
|
||||
// FIXME: HACK, use LogView instead?
|
||||
static void findNext(QPlainTextEdit * _this, const QString& what, bool reverse)
|
||||
{
|
||||
_this->find(what, reverse ? QTextDocument::FindFlag::FindBackward : QTextDocument::FindFlag(0));
|
||||
_this->find(what, reverse ? QTextDocument::FindFlag::FindBackward : QTextDocument::FindFlag(0));
|
||||
}
|
||||
|
||||
void OtherLogsPage::on_findButton_clicked()
|
||||
{
|
||||
auto modifiers = QApplication::keyboardModifiers();
|
||||
bool reverse = modifiers & Qt::ShiftModifier;
|
||||
findNext(ui->text, ui->searchBar->text(), reverse);
|
||||
auto modifiers = QApplication::keyboardModifiers();
|
||||
bool reverse = modifiers & Qt::ShiftModifier;
|
||||
findNext(ui->text, ui->searchBar->text(), reverse);
|
||||
}
|
||||
|
||||
void OtherLogsPage::findNextActivated()
|
||||
{
|
||||
findNext(ui->text, ui->searchBar->text(), false);
|
||||
findNext(ui->text, ui->searchBar->text(), false);
|
||||
}
|
||||
|
||||
void OtherLogsPage::findPreviousActivated()
|
||||
{
|
||||
findNext(ui->text, ui->searchBar->text(), true);
|
||||
findNext(ui->text, ui->searchBar->text(), true);
|
||||
}
|
||||
|
||||
void OtherLogsPage::findActivated()
|
||||
{
|
||||
// focus the search bar if it doesn't have focus
|
||||
if (!ui->searchBar->hasFocus())
|
||||
{
|
||||
ui->searchBar->setFocus();
|
||||
ui->searchBar->selectAll();
|
||||
}
|
||||
// focus the search bar if it doesn't have focus
|
||||
if (!ui->searchBar->hasFocus())
|
||||
{
|
||||
ui->searchBar->setFocus();
|
||||
ui->searchBar->selectAll();
|
||||
}
|
||||
}
|
||||
|
@ -30,52 +30,52 @@ class RecursiveFileSystemWatcher;
|
||||
|
||||
class OtherLogsPage : public QWidget, public BasePage
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit OtherLogsPage(QString path, IPathMatcher::Ptr fileFilter, QWidget *parent = 0);
|
||||
~OtherLogsPage();
|
||||
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 MMC->getThemedIcon("log");
|
||||
}
|
||||
QString helpPage() const override
|
||||
{
|
||||
return "Minecraft-Logs";
|
||||
}
|
||||
void openedImpl() override;
|
||||
void closedImpl() override;
|
||||
QString id() const override
|
||||
{
|
||||
return "logs";
|
||||
}
|
||||
QString displayName() const override
|
||||
{
|
||||
return tr("Other logs");
|
||||
}
|
||||
QIcon icon() const override
|
||||
{
|
||||
return MMC->getThemedIcon("log");
|
||||
}
|
||||
QString helpPage() const override
|
||||
{
|
||||
return "Minecraft-Logs";
|
||||
}
|
||||
void openedImpl() override;
|
||||
void closedImpl() override;
|
||||
|
||||
private slots:
|
||||
void populateSelectLogBox();
|
||||
void on_selectLogBox_currentIndexChanged(const int index);
|
||||
void on_btnReload_clicked();
|
||||
void on_btnPaste_clicked();
|
||||
void on_btnCopy_clicked();
|
||||
void on_btnDelete_clicked();
|
||||
void on_btnClean_clicked();
|
||||
void populateSelectLogBox();
|
||||
void on_selectLogBox_currentIndexChanged(const int index);
|
||||
void on_btnReload_clicked();
|
||||
void on_btnPaste_clicked();
|
||||
void on_btnCopy_clicked();
|
||||
void on_btnDelete_clicked();
|
||||
void on_btnClean_clicked();
|
||||
|
||||
void on_findButton_clicked();
|
||||
void findActivated();
|
||||
void findNextActivated();
|
||||
void findPreviousActivated();
|
||||
void on_findButton_clicked();
|
||||
void findActivated();
|
||||
void findNextActivated();
|
||||
void findPreviousActivated();
|
||||
|
||||
private:
|
||||
void setControlsEnabled(const bool enabled);
|
||||
void setControlsEnabled(const bool enabled);
|
||||
|
||||
private:
|
||||
Ui::OtherLogsPage *ui;
|
||||
QString m_path;
|
||||
QString m_currentFile;
|
||||
IPathMatcher::Ptr m_fileFilter;
|
||||
RecursiveFileSystemWatcher *m_watcher;
|
||||
Ui::OtherLogsPage *ui;
|
||||
QString m_path;
|
||||
QString m_currentFile;
|
||||
IPathMatcher::Ptr m_fileFilter;
|
||||
RecursiveFileSystemWatcher *m_watcher;
|
||||
};
|
||||
|
@ -5,17 +5,17 @@
|
||||
class ResourcePackPage : public ModFolderPage
|
||||
{
|
||||
public:
|
||||
explicit ResourcePackPage(MinecraftInstance *instance, QWidget *parent = 0)
|
||||
: ModFolderPage(instance, instance->resourcePackList(), "resourcepacks",
|
||||
"resourcepacks", tr("Resource packs"), "Resource-packs", parent)
|
||||
{
|
||||
ui->configFolderBtn->setHidden(true);
|
||||
}
|
||||
explicit ResourcePackPage(MinecraftInstance *instance, QWidget *parent = 0)
|
||||
: ModFolderPage(instance, instance->resourcePackList(), "resourcepacks",
|
||||
"resourcepacks", tr("Resource packs"), "Resource-packs", parent)
|
||||
{
|
||||
ui->configFolderBtn->setHidden(true);
|
||||
}
|
||||
|
||||
virtual ~ResourcePackPage() {}
|
||||
virtual bool shouldDisplay() const override
|
||||
{
|
||||
return !m_inst->traits().contains("no-texturepacks") &&
|
||||
!m_inst->traits().contains("texturepacks");
|
||||
}
|
||||
virtual ~ResourcePackPage() {}
|
||||
virtual bool shouldDisplay() const override
|
||||
{
|
||||
return !m_inst->traits().contains("no-texturepacks") &&
|
||||
!m_inst->traits().contains("texturepacks");
|
||||
}
|
||||
};
|
||||
|
@ -32,341 +32,341 @@ typedef std::shared_ptr<SharedIconCache> SharedIconCachePtr;
|
||||
|
||||
class ThumbnailingResult : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
public slots:
|
||||
inline void emitResultsReady(const QString &path) { emit resultsReady(path); }
|
||||
inline void emitResultsFailed(const QString &path) { emit resultsFailed(path); }
|
||||
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);
|
||||
void resultsReady(const QString &path);
|
||||
void resultsFailed(const QString &path);
|
||||
};
|
||||
|
||||
class ThumbnailRunnable : public QRunnable
|
||||
{
|
||||
public:
|
||||
ThumbnailRunnable(QString path, SharedIconCachePtr cache)
|
||||
{
|
||||
m_path = path;
|
||||
m_cache = cache;
|
||||
}
|
||||
void run()
|
||||
{
|
||||
QFileInfo info(m_path);
|
||||
if (info.isDir())
|
||||
return;
|
||||
if ((info.suffix().compare("png", Qt::CaseInsensitive) != 0))
|
||||
return;
|
||||
int tries = 5;
|
||||
while (tries)
|
||||
{
|
||||
if (!m_cache->stale(m_path))
|
||||
return;
|
||||
QImage image(m_path);
|
||||
if (image.isNull())
|
||||
{
|
||||
QThread::msleep(500);
|
||||
tries--;
|
||||
continue;
|
||||
}
|
||||
QImage small;
|
||||
if (image.width() > image.height())
|
||||
small = image.scaledToWidth(512).scaledToWidth(256, Qt::SmoothTransformation);
|
||||
else
|
||||
small = image.scaledToHeight(512).scaledToHeight(256, Qt::SmoothTransformation);
|
||||
QPoint offset((256 - small.width()) / 2, (256 - small.height()) / 2);
|
||||
QImage square(QSize(256, 256), QImage::Format_ARGB32);
|
||||
square.fill(Qt::transparent);
|
||||
ThumbnailRunnable(QString path, SharedIconCachePtr cache)
|
||||
{
|
||||
m_path = path;
|
||||
m_cache = cache;
|
||||
}
|
||||
void run()
|
||||
{
|
||||
QFileInfo info(m_path);
|
||||
if (info.isDir())
|
||||
return;
|
||||
if ((info.suffix().compare("png", Qt::CaseInsensitive) != 0))
|
||||
return;
|
||||
int tries = 5;
|
||||
while (tries)
|
||||
{
|
||||
if (!m_cache->stale(m_path))
|
||||
return;
|
||||
QImage image(m_path);
|
||||
if (image.isNull())
|
||||
{
|
||||
QThread::msleep(500);
|
||||
tries--;
|
||||
continue;
|
||||
}
|
||||
QImage small;
|
||||
if (image.width() > image.height())
|
||||
small = image.scaledToWidth(512).scaledToWidth(256, Qt::SmoothTransformation);
|
||||
else
|
||||
small = image.scaledToHeight(512).scaledToHeight(256, Qt::SmoothTransformation);
|
||||
QPoint offset((256 - small.width()) / 2, (256 - small.height()) / 2);
|
||||
QImage square(QSize(256, 256), QImage::Format_ARGB32);
|
||||
square.fill(Qt::transparent);
|
||||
|
||||
QPainter painter(&square);
|
||||
painter.drawImage(offset, small);
|
||||
painter.end();
|
||||
QPainter painter(&square);
|
||||
painter.drawImage(offset, small);
|
||||
painter.end();
|
||||
|
||||
QIcon icon(QPixmap::fromImage(square));
|
||||
m_cache->add(m_path, icon);
|
||||
m_resultEmitter.emitResultsReady(m_path);
|
||||
return;
|
||||
}
|
||||
m_resultEmitter.emitResultsFailed(m_path);
|
||||
}
|
||||
QString m_path;
|
||||
SharedIconCachePtr m_cache;
|
||||
ThumbnailingResult m_resultEmitter;
|
||||
QIcon icon(QPixmap::fromImage(square));
|
||||
m_cache->add(m_path, icon);
|
||||
m_resultEmitter.emitResultsReady(m_path);
|
||||
return;
|
||||
}
|
||||
m_resultEmitter.emitResultsFailed(m_path);
|
||||
}
|
||||
QString m_path;
|
||||
SharedIconCachePtr m_cache;
|
||||
ThumbnailingResult m_resultEmitter;
|
||||
};
|
||||
|
||||
// this is about as elegant and well written as a bag of bricks with scribbles done by insane
|
||||
// asylum patients.
|
||||
class FilterModel : public QIdentityProxyModel
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit FilterModel(QObject *parent = 0) : QIdentityProxyModel(parent)
|
||||
{
|
||||
m_thumbnailingPool.setMaxThreadCount(4);
|
||||
m_thumbnailCache = std::make_shared<SharedIconCache>();
|
||||
m_thumbnailCache->add("placeholder", MMC->getThemedIcon("screenshot-placeholder"));
|
||||
connect(&watcher, SIGNAL(fileChanged(QString)), SLOT(fileChanged(QString)));
|
||||
// FIXME: the watched file set is not updated when files are removed
|
||||
}
|
||||
virtual ~FilterModel() { m_thumbnailingPool.waitForDone(500); }
|
||||
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)
|
||||
{
|
||||
QVariant result = sourceModel()->data(mapToSource(proxyIndex), role);
|
||||
return result.toString().remove(QRegExp("\\.png$"));
|
||||
}
|
||||
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 (m_thumbnailCache->get(filePath, temp))
|
||||
{
|
||||
return temp;
|
||||
}
|
||||
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)
|
||||
{
|
||||
auto model = sourceModel();
|
||||
if (!model)
|
||||
return false;
|
||||
if (role != Qt::EditRole)
|
||||
return false;
|
||||
// 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);
|
||||
}
|
||||
return model->setData(mapToSource(index), value.toString() + ".png", role);
|
||||
}
|
||||
explicit FilterModel(QObject *parent = 0) : QIdentityProxyModel(parent)
|
||||
{
|
||||
m_thumbnailingPool.setMaxThreadCount(4);
|
||||
m_thumbnailCache = std::make_shared<SharedIconCache>();
|
||||
m_thumbnailCache->add("placeholder", MMC->getThemedIcon("screenshot-placeholder"));
|
||||
connect(&watcher, SIGNAL(fileChanged(QString)), SLOT(fileChanged(QString)));
|
||||
// FIXME: the watched file set is not updated when files are removed
|
||||
}
|
||||
virtual ~FilterModel() { m_thumbnailingPool.waitForDone(500); }
|
||||
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)
|
||||
{
|
||||
QVariant result = sourceModel()->data(mapToSource(proxyIndex), role);
|
||||
return result.toString().remove(QRegExp("\\.png$"));
|
||||
}
|
||||
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 (m_thumbnailCache->get(filePath, temp))
|
||||
{
|
||||
return temp;
|
||||
}
|
||||
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)
|
||||
{
|
||||
auto model = sourceModel();
|
||||
if (!model)
|
||||
return false;
|
||||
if (role != Qt::EditRole)
|
||||
return false;
|
||||
// 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);
|
||||
}
|
||||
return model->setData(mapToSource(index), value.toString() + ".png", role);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
private slots:
|
||||
void thumbnailReady(QString path) { emit layoutChanged(); }
|
||||
void thumbnailFailed(QString path) { m_failed.insert(path); }
|
||||
void fileChanged(QString filepath)
|
||||
{
|
||||
m_thumbnailCache->setStale(filepath);
|
||||
thumbnailImage(filepath);
|
||||
// reinsert the path...
|
||||
watcher.removePath(filepath);
|
||||
watcher.addPath(filepath);
|
||||
}
|
||||
void thumbnailReady(QString path) { emit layoutChanged(); }
|
||||
void thumbnailFailed(QString path) { m_failed.insert(path); }
|
||||
void fileChanged(QString filepath)
|
||||
{
|
||||
m_thumbnailCache->setStale(filepath);
|
||||
thumbnailImage(filepath);
|
||||
// reinsert the path...
|
||||
watcher.removePath(filepath);
|
||||
watcher.addPath(filepath);
|
||||
}
|
||||
|
||||
private:
|
||||
SharedIconCachePtr m_thumbnailCache;
|
||||
QThreadPool m_thumbnailingPool;
|
||||
QSet<QString> m_failed;
|
||||
QSet<QString> watched;
|
||||
QFileSystemWatcher watcher;
|
||||
SharedIconCachePtr m_thumbnailCache;
|
||||
QThreadPool m_thumbnailingPool;
|
||||
QSet<QString> m_failed;
|
||||
QSet<QString> watched;
|
||||
QFileSystemWatcher watcher;
|
||||
};
|
||||
|
||||
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
|
||||
{
|
||||
auto widget = QStyledItemDelegate::createEditor(parent, option, index);
|
||||
auto foo = dynamic_cast<QLineEdit *>(widget);
|
||||
if (foo)
|
||||
{
|
||||
foo->setAlignment(Qt::AlignHCenter);
|
||||
foo->setFrame(true);
|
||||
foo->setMaximumWidth(192);
|
||||
}
|
||||
return widget;
|
||||
}
|
||||
explicit CenteredEditingDelegate(QObject *parent = 0) : QStyledItemDelegate(parent) {}
|
||||
virtual ~CenteredEditingDelegate() {}
|
||||
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)
|
||||
{
|
||||
foo->setAlignment(Qt::AlignHCenter);
|
||||
foo->setFrame(true);
|
||||
foo->setMaximumWidth(192);
|
||||
}
|
||||
return widget;
|
||||
}
|
||||
};
|
||||
|
||||
ScreenshotsPage::ScreenshotsPage(QString path, QWidget *parent)
|
||||
: QWidget(parent), ui(new Ui::ScreenshotsPage)
|
||||
: QWidget(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 | QDir::Writable | QDir::Readable);
|
||||
m_model->setReadOnly(false);
|
||||
m_model->setNameFilters({"*.png"});
|
||||
m_model->setNameFilterDisables(false);
|
||||
m_folder = path;
|
||||
m_valid = FS::ensureFolderPathExists(m_folder);
|
||||
m_model.reset(new QFileSystemModel());
|
||||
m_filterModel.reset(new FilterModel());
|
||||
m_filterModel->setSourceModel(m_model.get());
|
||||
m_model->setFilter(QDir::Files | QDir::Writable | QDir::Readable);
|
||||
m_model->setReadOnly(false);
|
||||
m_model->setNameFilters({"*.png"});
|
||||
m_model->setNameFilterDisables(false);
|
||||
m_folder = path;
|
||||
m_valid = FS::ensureFolderPathExists(m_folder);
|
||||
|
||||
ui->setupUi(this);
|
||||
ui->tabWidget->tabBar()->hide();
|
||||
ui->listView->setIconSize(QSize(128, 128));
|
||||
ui->listView->setGridSize(QSize(192, 160));
|
||||
ui->listView->setSpacing(9);
|
||||
// ui->listView->setUniformItemSizes(true);
|
||||
ui->listView->setLayoutMode(QListView::Batched);
|
||||
ui->listView->setViewMode(QListView::IconMode);
|
||||
ui->listView->setResizeMode(QListView::Adjust);
|
||||
ui->listView->installEventFilter(this);
|
||||
ui->listView->setEditTriggers(0);
|
||||
ui->listView->setItemDelegate(new CenteredEditingDelegate(this));
|
||||
connect(ui->listView, SIGNAL(activated(QModelIndex)), SLOT(onItemActivated(QModelIndex)));
|
||||
ui->setupUi(this);
|
||||
ui->tabWidget->tabBar()->hide();
|
||||
ui->listView->setIconSize(QSize(128, 128));
|
||||
ui->listView->setGridSize(QSize(192, 160));
|
||||
ui->listView->setSpacing(9);
|
||||
// ui->listView->setUniformItemSizes(true);
|
||||
ui->listView->setLayoutMode(QListView::Batched);
|
||||
ui->listView->setViewMode(QListView::IconMode);
|
||||
ui->listView->setResizeMode(QListView::Adjust);
|
||||
ui->listView->installEventFilter(this);
|
||||
ui->listView->setEditTriggers(0);
|
||||
ui->listView->setItemDelegate(new CenteredEditingDelegate(this));
|
||||
connect(ui->listView, SIGNAL(activated(QModelIndex)), SLOT(onItemActivated(QModelIndex)));
|
||||
}
|
||||
|
||||
bool ScreenshotsPage::eventFilter(QObject *obj, QEvent *evt)
|
||||
{
|
||||
if (obj != ui->listView)
|
||||
return QWidget::eventFilter(obj, evt);
|
||||
if (evt->type() != QEvent::KeyPress)
|
||||
{
|
||||
return QWidget::eventFilter(obj, evt);
|
||||
}
|
||||
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(evt);
|
||||
switch (keyEvent->key())
|
||||
{
|
||||
case Qt::Key_Delete:
|
||||
on_deleteBtn_clicked();
|
||||
return true;
|
||||
case Qt::Key_F2:
|
||||
on_renameBtn_clicked();
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return QWidget::eventFilter(obj, evt);
|
||||
if (obj != ui->listView)
|
||||
return QWidget::eventFilter(obj, evt);
|
||||
if (evt->type() != QEvent::KeyPress)
|
||||
{
|
||||
return QWidget::eventFilter(obj, evt);
|
||||
}
|
||||
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(evt);
|
||||
switch (keyEvent->key())
|
||||
{
|
||||
case Qt::Key_Delete:
|
||||
on_deleteBtn_clicked();
|
||||
return true;
|
||||
case Qt::Key_F2:
|
||||
on_renameBtn_clicked();
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return QWidget::eventFilter(obj, evt);
|
||||
}
|
||||
|
||||
ScreenshotsPage::~ScreenshotsPage()
|
||||
{
|
||||
delete ui;
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void ScreenshotsPage::onItemActivated(QModelIndex index)
|
||||
{
|
||||
if (!index.isValid())
|
||||
return;
|
||||
auto info = m_model->fileInfo(index);
|
||||
QString fileName = info.absoluteFilePath();
|
||||
DesktopServices::openFile(info.absoluteFilePath());
|
||||
if (!index.isValid())
|
||||
return;
|
||||
auto info = m_model->fileInfo(index);
|
||||
QString fileName = info.absoluteFilePath();
|
||||
DesktopServices::openFile(info.absoluteFilePath());
|
||||
}
|
||||
|
||||
void ScreenshotsPage::on_viewFolderBtn_clicked()
|
||||
{
|
||||
DesktopServices::openDirectory(m_folder, true);
|
||||
DesktopServices::openDirectory(m_folder, true);
|
||||
}
|
||||
|
||||
void ScreenshotsPage::on_uploadBtn_clicked()
|
||||
{
|
||||
auto selection = ui->listView->selectionModel()->selectedRows();
|
||||
if (selection.isEmpty())
|
||||
return;
|
||||
auto selection = ui->listView->selectionModel()->selectedRows();
|
||||
if (selection.isEmpty())
|
||||
return;
|
||||
|
||||
QList<ScreenshotPtr> uploaded;
|
||||
auto job = NetJobPtr(new NetJob("Screenshot Upload"));
|
||||
for (auto item : selection)
|
||||
{
|
||||
auto info = m_model->fileInfo(item);
|
||||
auto screenshot = std::make_shared<ScreenShot>(info);
|
||||
uploaded.push_back(screenshot);
|
||||
job->addNetAction(ImgurUpload::make(screenshot));
|
||||
}
|
||||
SequentialTask task;
|
||||
auto albumTask = NetJobPtr(new NetJob("Imgur Album Creation"));
|
||||
auto imgurAlbum = ImgurAlbumCreation::make(uploaded);
|
||||
albumTask->addNetAction(imgurAlbum);
|
||||
task.addTask(job.unwrap());
|
||||
task.addTask(albumTask.unwrap());
|
||||
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
|
||||
{
|
||||
auto link = QString("https://imgur.com/a/%1").arg(imgurAlbum->id());
|
||||
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();
|
||||
}
|
||||
m_uploadActive = false;
|
||||
QList<ScreenshotPtr> uploaded;
|
||||
auto job = NetJobPtr(new NetJob("Screenshot Upload"));
|
||||
for (auto item : selection)
|
||||
{
|
||||
auto info = m_model->fileInfo(item);
|
||||
auto screenshot = std::make_shared<ScreenShot>(info);
|
||||
uploaded.push_back(screenshot);
|
||||
job->addNetAction(ImgurUpload::make(screenshot));
|
||||
}
|
||||
SequentialTask task;
|
||||
auto albumTask = NetJobPtr(new NetJob("Imgur Album Creation"));
|
||||
auto imgurAlbum = ImgurAlbumCreation::make(uploaded);
|
||||
albumTask->addNetAction(imgurAlbum);
|
||||
task.addTask(job.unwrap());
|
||||
task.addTask(albumTask.unwrap());
|
||||
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
|
||||
{
|
||||
auto link = QString("https://imgur.com/a/%1").arg(imgurAlbum->id());
|
||||
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();
|
||||
}
|
||||
m_uploadActive = false;
|
||||
}
|
||||
|
||||
void ScreenshotsPage::on_deleteBtn_clicked()
|
||||
{
|
||||
auto mbox = CustomMessageBox::selectable(
|
||||
this, tr("Are you sure?"), tr("This will delete all selected screenshots."),
|
||||
QMessageBox::Warning, QMessageBox::Yes | QMessageBox::No);
|
||||
std::unique_ptr<QMessageBox> box(mbox);
|
||||
auto mbox = CustomMessageBox::selectable(
|
||||
this, tr("Are you sure?"), tr("This will delete all selected screenshots."),
|
||||
QMessageBox::Warning, QMessageBox::Yes | QMessageBox::No);
|
||||
std::unique_ptr<QMessageBox> box(mbox);
|
||||
|
||||
if (box->exec() != QMessageBox::Yes)
|
||||
return;
|
||||
if (box->exec() != QMessageBox::Yes)
|
||||
return;
|
||||
|
||||
auto selected = ui->listView->selectionModel()->selectedIndexes();
|
||||
for (auto item : selected)
|
||||
{
|
||||
m_model->remove(item);
|
||||
}
|
||||
auto selected = ui->listView->selectionModel()->selectedIndexes();
|
||||
for (auto item : selected)
|
||||
{
|
||||
m_model->remove(item);
|
||||
}
|
||||
}
|
||||
|
||||
void ScreenshotsPage::on_renameBtn_clicked()
|
||||
{
|
||||
auto selection = ui->listView->selectionModel()->selectedIndexes();
|
||||
if (selection.isEmpty())
|
||||
return;
|
||||
ui->listView->edit(selection[0]);
|
||||
// TODO: mass renaming
|
||||
auto selection = ui->listView->selectionModel()->selectedIndexes();
|
||||
if (selection.isEmpty())
|
||||
return;
|
||||
ui->listView->edit(selection[0]);
|
||||
// TODO: mass renaming
|
||||
}
|
||||
|
||||
void ScreenshotsPage::openedImpl()
|
||||
{
|
||||
if(!m_valid)
|
||||
{
|
||||
m_valid = FS::ensureFolderPathExists(m_folder);
|
||||
}
|
||||
if (m_valid)
|
||||
{
|
||||
QString path = QDir(m_folder).absolutePath();
|
||||
auto idx = m_model->setRootPath(path);
|
||||
if(idx.isValid())
|
||||
{
|
||||
ui->listView->setModel(m_filterModel.get());
|
||||
ui->listView->setRootIndex(m_filterModel->mapFromSource(idx));
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->listView->setModel(nullptr);
|
||||
}
|
||||
}
|
||||
if(!m_valid)
|
||||
{
|
||||
m_valid = FS::ensureFolderPathExists(m_folder);
|
||||
}
|
||||
if (m_valid)
|
||||
{
|
||||
QString path = QDir(m_folder).absolutePath();
|
||||
auto idx = m_model->setRootPath(path);
|
||||
if(idx.isValid())
|
||||
{
|
||||
ui->listView->setModel(m_filterModel.get());
|
||||
ui->listView->setRootIndex(m_filterModel->mapFromSource(idx));
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->listView->setModel(nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#include "ScreenshotsPage.moc"
|
||||
|
@ -33,52 +33,52 @@ class ImgurAlbumCreation;
|
||||
|
||||
class ScreenshotsPage : public QWidget, public BasePage
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ScreenshotsPage(QString path, QWidget *parent = 0);
|
||||
virtual ~ScreenshotsPage();
|
||||
explicit ScreenshotsPage(QString path, QWidget *parent = 0);
|
||||
virtual ~ScreenshotsPage();
|
||||
|
||||
virtual void openedImpl() override;
|
||||
virtual void openedImpl() 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 MMC->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 MMC->getThemedIcon("screenshots");
|
||||
}
|
||||
virtual QString id() const override
|
||||
{
|
||||
return "screenshots";
|
||||
}
|
||||
virtual QString helpPage() const override
|
||||
{
|
||||
return "Screenshots-management";
|
||||
}
|
||||
virtual bool apply() override
|
||||
{
|
||||
return !m_uploadActive;
|
||||
}
|
||||
private slots:
|
||||
void on_uploadBtn_clicked();
|
||||
void on_deleteBtn_clicked();
|
||||
void on_renameBtn_clicked();
|
||||
void on_viewFolderBtn_clicked();
|
||||
void onItemActivated(QModelIndex);
|
||||
void on_uploadBtn_clicked();
|
||||
void on_deleteBtn_clicked();
|
||||
void on_renameBtn_clicked();
|
||||
void on_viewFolderBtn_clicked();
|
||||
void onItemActivated(QModelIndex);
|
||||
|
||||
private:
|
||||
Ui::ScreenshotsPage *ui;
|
||||
std::shared_ptr<QFileSystemModel> m_model;
|
||||
std::shared_ptr<QIdentityProxyModel> m_filterModel;
|
||||
QString m_folder;
|
||||
bool m_valid = false;
|
||||
bool m_uploadActive = false;
|
||||
Ui::ScreenshotsPage *ui;
|
||||
std::shared_ptr<QFileSystemModel> m_model;
|
||||
std::shared_ptr<QIdentityProxyModel> m_filterModel;
|
||||
QString m_folder;
|
||||
bool m_valid = false;
|
||||
bool m_uploadActive = false;
|
||||
};
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -32,55 +32,55 @@ class MinecraftInstance;
|
||||
|
||||
class ServersPage : public QWidget, public BasePage
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ServersPage(MinecraftInstance *inst, QWidget *parent = 0);
|
||||
virtual ~ServersPage();
|
||||
explicit ServersPage(MinecraftInstance *inst, QWidget *parent = 0);
|
||||
virtual ~ServersPage();
|
||||
|
||||
void openedImpl() override;
|
||||
void closedImpl() override;
|
||||
void openedImpl() override;
|
||||
void closedImpl() override;
|
||||
|
||||
virtual QString displayName() const override
|
||||
{
|
||||
return tr("Servers");
|
||||
}
|
||||
virtual QIcon icon() const override
|
||||
{
|
||||
return MMC->getThemedIcon("unknown_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 MMC->getThemedIcon("unknown_server");
|
||||
}
|
||||
virtual QString id() const override
|
||||
{
|
||||
return "servers";
|
||||
}
|
||||
virtual QString helpPage() const override
|
||||
{
|
||||
return "Servers-management";
|
||||
}
|
||||
private:
|
||||
void updateState();
|
||||
void scheduleSave();
|
||||
bool saveIsScheduled() const;
|
||||
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);
|
||||
void currentChanged(const QModelIndex ¤t, const QModelIndex &previous);
|
||||
void rowsRemoved(const QModelIndex &parent, int first, int last);
|
||||
|
||||
void on_addBtn_clicked();
|
||||
void on_removeBtn_clicked();
|
||||
void on_moveUpBtn_clicked();
|
||||
void on_moveDownBtn_clicked();
|
||||
void on_RunningState_changed(bool running);
|
||||
void on_addBtn_clicked();
|
||||
void on_removeBtn_clicked();
|
||||
void on_moveUpBtn_clicked();
|
||||
void on_moveDownBtn_clicked();
|
||||
void on_RunningState_changed(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);
|
||||
|
||||
private: // data
|
||||
int currentServer = -1;
|
||||
bool m_locked = true;
|
||||
Ui::ServersPage *ui = nullptr;
|
||||
ServersModel * m_model = nullptr;
|
||||
MinecraftInstance * m_inst = nullptr;
|
||||
int currentServer = -1;
|
||||
bool m_locked = true;
|
||||
Ui::ServersPage *ui = nullptr;
|
||||
ServersModel * m_model = nullptr;
|
||||
MinecraftInstance * m_inst = nullptr;
|
||||
};
|
||||
|
||||
|
@ -5,15 +5,15 @@
|
||||
class TexturePackPage : public ModFolderPage
|
||||
{
|
||||
public:
|
||||
explicit TexturePackPage(MinecraftInstance *instance, QWidget *parent = 0)
|
||||
: ModFolderPage(instance, instance->texturePackList(), "texturepacks", "resourcepacks",
|
||||
tr("Texture packs"), "Texture-packs", parent)
|
||||
{
|
||||
ui->configFolderBtn->setHidden(true);
|
||||
}
|
||||
virtual ~TexturePackPage() {}
|
||||
virtual bool shouldDisplay() const override
|
||||
{
|
||||
return m_inst->traits().contains("texturepacks");
|
||||
}
|
||||
explicit TexturePackPage(MinecraftInstance *instance, QWidget *parent = 0)
|
||||
: ModFolderPage(instance, instance->texturePackList(), "texturepacks", "resourcepacks",
|
||||
tr("Texture packs"), "Texture-packs", parent)
|
||||
{
|
||||
ui->configFolderBtn->setHidden(true);
|
||||
}
|
||||
virtual ~TexturePackPage() {}
|
||||
virtual bool shouldDisplay() const override
|
||||
{
|
||||
return m_inst->traits().contains("texturepacks");
|
||||
}
|
||||
};
|
||||
|
@ -49,521 +49,521 @@
|
||||
|
||||
class IconProxy : public QIdentityProxyModel
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
IconProxy(QWidget *parentWidget) : QIdentityProxyModel(parentWidget)
|
||||
{
|
||||
connect(parentWidget, &QObject::destroyed, this, &IconProxy::widgetGone);
|
||||
m_parentWidget = parentWidget;
|
||||
}
|
||||
IconProxy(QWidget *parentWidget) : QIdentityProxyModel(parentWidget)
|
||||
{
|
||||
connect(parentWidget, &QObject::destroyed, this, &IconProxy::widgetGone);
|
||||
m_parentWidget = parentWidget;
|
||||
}
|
||||
|
||||
virtual QVariant data(const QModelIndex &proxyIndex, int role = Qt::DisplayRole) const override
|
||||
{
|
||||
QVariant var = QIdentityProxyModel::data(mapToSource(proxyIndex), role);
|
||||
int column = proxyIndex.column();
|
||||
if(column == 0 && role == Qt::DecorationRole && m_parentWidget)
|
||||
{
|
||||
if(!var.isNull())
|
||||
{
|
||||
auto string = var.toString();
|
||||
if(string == "warning")
|
||||
{
|
||||
return MMC->getThemedIcon("status-yellow");
|
||||
}
|
||||
else if(string == "error")
|
||||
{
|
||||
return MMC->getThemedIcon("status-bad");
|
||||
}
|
||||
}
|
||||
return MMC->getThemedIcon("status-good");
|
||||
}
|
||||
return var;
|
||||
}
|
||||
virtual QVariant data(const QModelIndex &proxyIndex, int role = Qt::DisplayRole) const override
|
||||
{
|
||||
QVariant var = QIdentityProxyModel::data(mapToSource(proxyIndex), role);
|
||||
int column = proxyIndex.column();
|
||||
if(column == 0 && role == Qt::DecorationRole && m_parentWidget)
|
||||
{
|
||||
if(!var.isNull())
|
||||
{
|
||||
auto string = var.toString();
|
||||
if(string == "warning")
|
||||
{
|
||||
return MMC->getThemedIcon("status-yellow");
|
||||
}
|
||||
else if(string == "error")
|
||||
{
|
||||
return MMC->getThemedIcon("status-bad");
|
||||
}
|
||||
}
|
||||
return MMC->getThemedIcon("status-good");
|
||||
}
|
||||
return var;
|
||||
}
|
||||
private slots:
|
||||
void widgetGone()
|
||||
{
|
||||
m_parentWidget = nullptr;
|
||||
}
|
||||
void widgetGone()
|
||||
{
|
||||
m_parentWidget = nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
QWidget *m_parentWidget = nullptr;
|
||||
QWidget *m_parentWidget = nullptr;
|
||||
};
|
||||
|
||||
QIcon VersionPage::icon() const
|
||||
{
|
||||
return MMC->icons()->getIcon(m_inst->iconKey());
|
||||
return MMC->icons()->getIcon(m_inst->iconKey());
|
||||
}
|
||||
bool VersionPage::shouldDisplay() const
|
||||
{
|
||||
return !m_inst->isRunning();
|
||||
return !m_inst->isRunning();
|
||||
}
|
||||
|
||||
VersionPage::VersionPage(MinecraftInstance *inst, QWidget *parent)
|
||||
: QWidget(parent), ui(new Ui::VersionPage), m_inst(inst)
|
||||
: QWidget(parent), ui(new Ui::VersionPage), m_inst(inst)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->tabWidget->tabBar()->hide();
|
||||
m_profile = m_inst->getComponentList();
|
||||
ui->setupUi(this);
|
||||
ui->tabWidget->tabBar()->hide();
|
||||
m_profile = m_inst->getComponentList();
|
||||
|
||||
reloadComponentList();
|
||||
reloadComponentList();
|
||||
|
||||
if (m_profile)
|
||||
{
|
||||
auto proxy = new IconProxy(ui->packageView);
|
||||
proxy->setSourceModel(m_profile.get());
|
||||
ui->packageView->setModel(proxy);
|
||||
ui->packageView->installEventFilter(this);
|
||||
ui->packageView->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
connect(ui->packageView->selectionModel(), &QItemSelectionModel::currentChanged, this, &VersionPage::versionCurrent);
|
||||
auto smodel = ui->packageView->selectionModel();
|
||||
connect(smodel, &QItemSelectionModel::currentChanged, this, &VersionPage::packageCurrent);
|
||||
updateVersionControls();
|
||||
// select first item.
|
||||
preselect(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
disableVersionControls();
|
||||
}
|
||||
connect(m_inst, &MinecraftInstance::versionReloaded, this,
|
||||
&VersionPage::updateVersionControls);
|
||||
if (m_profile)
|
||||
{
|
||||
auto proxy = new IconProxy(ui->packageView);
|
||||
proxy->setSourceModel(m_profile.get());
|
||||
ui->packageView->setModel(proxy);
|
||||
ui->packageView->installEventFilter(this);
|
||||
ui->packageView->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
connect(ui->packageView->selectionModel(), &QItemSelectionModel::currentChanged, this, &VersionPage::versionCurrent);
|
||||
auto smodel = ui->packageView->selectionModel();
|
||||
connect(smodel, &QItemSelectionModel::currentChanged, this, &VersionPage::packageCurrent);
|
||||
updateVersionControls();
|
||||
// select first item.
|
||||
preselect(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
disableVersionControls();
|
||||
}
|
||||
connect(m_inst, &MinecraftInstance::versionReloaded, this,
|
||||
&VersionPage::updateVersionControls);
|
||||
}
|
||||
|
||||
VersionPage::~VersionPage()
|
||||
{
|
||||
delete ui;
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void VersionPage::packageCurrent(const QModelIndex ¤t, const QModelIndex &previous)
|
||||
{
|
||||
if (!current.isValid())
|
||||
{
|
||||
ui->frame->clear();
|
||||
return;
|
||||
}
|
||||
int row = current.row();
|
||||
auto patch = m_profile->getComponent(row);
|
||||
auto severity = patch->getProblemSeverity();
|
||||
switch(severity)
|
||||
{
|
||||
case ProblemSeverity::Warning:
|
||||
ui->frame->setModText(tr("%1 possibly has issues.").arg(patch->getName()));
|
||||
break;
|
||||
case ProblemSeverity::Error:
|
||||
ui->frame->setModText(tr("%1 has issues!").arg(patch->getName()));
|
||||
break;
|
||||
default:
|
||||
case ProblemSeverity::None:
|
||||
ui->frame->clear();
|
||||
return;
|
||||
}
|
||||
if (!current.isValid())
|
||||
{
|
||||
ui->frame->clear();
|
||||
return;
|
||||
}
|
||||
int row = current.row();
|
||||
auto patch = m_profile->getComponent(row);
|
||||
auto severity = patch->getProblemSeverity();
|
||||
switch(severity)
|
||||
{
|
||||
case ProblemSeverity::Warning:
|
||||
ui->frame->setModText(tr("%1 possibly has issues.").arg(patch->getName()));
|
||||
break;
|
||||
case ProblemSeverity::Error:
|
||||
ui->frame->setModText(tr("%1 has issues!").arg(patch->getName()));
|
||||
break;
|
||||
default:
|
||||
case ProblemSeverity::None:
|
||||
ui->frame->clear();
|
||||
return;
|
||||
}
|
||||
|
||||
auto &problems = patch->getProblems();
|
||||
QString problemOut;
|
||||
for (auto &problem: problems)
|
||||
{
|
||||
if(problem.m_severity == ProblemSeverity::Error)
|
||||
{
|
||||
problemOut += tr("Error: ");
|
||||
}
|
||||
else if(problem.m_severity == ProblemSeverity::Warning)
|
||||
{
|
||||
problemOut += tr("Warning: ");
|
||||
}
|
||||
problemOut += problem.m_description;
|
||||
problemOut += "\n";
|
||||
}
|
||||
ui->frame->setModDescription(problemOut);
|
||||
auto &problems = patch->getProblems();
|
||||
QString problemOut;
|
||||
for (auto &problem: problems)
|
||||
{
|
||||
if(problem.m_severity == ProblemSeverity::Error)
|
||||
{
|
||||
problemOut += tr("Error: ");
|
||||
}
|
||||
else if(problem.m_severity == ProblemSeverity::Warning)
|
||||
{
|
||||
problemOut += tr("Warning: ");
|
||||
}
|
||||
problemOut += problem.m_description;
|
||||
problemOut += "\n";
|
||||
}
|
||||
ui->frame->setModDescription(problemOut);
|
||||
}
|
||||
|
||||
|
||||
void VersionPage::updateVersionControls()
|
||||
{
|
||||
ui->forgeBtn->setEnabled(true);
|
||||
ui->liteloaderBtn->setEnabled(true);
|
||||
updateButtons();
|
||||
ui->forgeBtn->setEnabled(true);
|
||||
ui->liteloaderBtn->setEnabled(true);
|
||||
updateButtons();
|
||||
}
|
||||
|
||||
void VersionPage::disableVersionControls()
|
||||
{
|
||||
ui->forgeBtn->setEnabled(false);
|
||||
ui->liteloaderBtn->setEnabled(false);
|
||||
ui->reloadBtn->setEnabled(false);
|
||||
updateButtons();
|
||||
ui->forgeBtn->setEnabled(false);
|
||||
ui->liteloaderBtn->setEnabled(false);
|
||||
ui->reloadBtn->setEnabled(false);
|
||||
updateButtons();
|
||||
}
|
||||
|
||||
bool VersionPage::reloadComponentList()
|
||||
{
|
||||
try
|
||||
{
|
||||
m_profile->reload(Net::Mode::Online);
|
||||
return true;
|
||||
}
|
||||
catch (const Exception &e)
|
||||
{
|
||||
QMessageBox::critical(this, tr("Error"), e.cause());
|
||||
return false;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
QMessageBox::critical(
|
||||
this, tr("Error"),
|
||||
tr("Couldn't load the instance profile."));
|
||||
return false;
|
||||
}
|
||||
try
|
||||
{
|
||||
m_profile->reload(Net::Mode::Online);
|
||||
return true;
|
||||
}
|
||||
catch (const Exception &e)
|
||||
{
|
||||
QMessageBox::critical(this, tr("Error"), e.cause());
|
||||
return false;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
QMessageBox::critical(
|
||||
this, tr("Error"),
|
||||
tr("Couldn't load the instance profile."));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void VersionPage::on_reloadBtn_clicked()
|
||||
{
|
||||
reloadComponentList();
|
||||
m_container->refreshContainer();
|
||||
reloadComponentList();
|
||||
m_container->refreshContainer();
|
||||
}
|
||||
|
||||
void VersionPage::on_removeBtn_clicked()
|
||||
{
|
||||
if (ui->packageView->currentIndex().isValid())
|
||||
{
|
||||
// FIXME: use actual model, not reloading.
|
||||
if (!m_profile->remove(ui->packageView->currentIndex().row()))
|
||||
{
|
||||
QMessageBox::critical(this, tr("Error"), tr("Couldn't remove file"));
|
||||
}
|
||||
}
|
||||
updateButtons();
|
||||
reloadComponentList();
|
||||
m_container->refreshContainer();
|
||||
if (ui->packageView->currentIndex().isValid())
|
||||
{
|
||||
// FIXME: use actual model, not reloading.
|
||||
if (!m_profile->remove(ui->packageView->currentIndex().row()))
|
||||
{
|
||||
QMessageBox::critical(this, tr("Error"), tr("Couldn't remove file"));
|
||||
}
|
||||
}
|
||||
updateButtons();
|
||||
reloadComponentList();
|
||||
m_container->refreshContainer();
|
||||
}
|
||||
|
||||
void VersionPage::on_modBtn_clicked()
|
||||
{
|
||||
if(m_container)
|
||||
{
|
||||
m_container->selectPage("mods");
|
||||
}
|
||||
if(m_container)
|
||||
{
|
||||
m_container->selectPage("mods");
|
||||
}
|
||||
}
|
||||
|
||||
void VersionPage::on_jarmodBtn_clicked()
|
||||
{
|
||||
auto list = GuiUtil::BrowseForFiles("jarmod", tr("Select jar mods"), tr("Minecraft.jar mods (*.zip *.jar)"), MMC->settings()->get("CentralModsDir").toString(), this->parentWidget());
|
||||
if(!list.empty())
|
||||
{
|
||||
m_profile->installJarMods(list);
|
||||
}
|
||||
updateButtons();
|
||||
auto list = GuiUtil::BrowseForFiles("jarmod", tr("Select jar mods"), tr("Minecraft.jar mods (*.zip *.jar)"), MMC->settings()->get("CentralModsDir").toString(), this->parentWidget());
|
||||
if(!list.empty())
|
||||
{
|
||||
m_profile->installJarMods(list);
|
||||
}
|
||||
updateButtons();
|
||||
}
|
||||
|
||||
void VersionPage::on_jarBtn_clicked()
|
||||
{
|
||||
auto jarPath = GuiUtil::BrowseForFile("jar", tr("Select jar"), tr("Minecraft.jar replacement (*.jar)"), MMC->settings()->get("CentralModsDir").toString(), this->parentWidget());
|
||||
if(!jarPath.isEmpty())
|
||||
{
|
||||
m_profile->installCustomJar(jarPath);
|
||||
}
|
||||
updateButtons();
|
||||
auto jarPath = GuiUtil::BrowseForFile("jar", tr("Select jar"), tr("Minecraft.jar replacement (*.jar)"), MMC->settings()->get("CentralModsDir").toString(), this->parentWidget());
|
||||
if(!jarPath.isEmpty())
|
||||
{
|
||||
m_profile->installCustomJar(jarPath);
|
||||
}
|
||||
updateButtons();
|
||||
}
|
||||
|
||||
void VersionPage::on_moveUpBtn_clicked()
|
||||
{
|
||||
try
|
||||
{
|
||||
m_profile->move(currentRow(), ComponentList::MoveUp);
|
||||
}
|
||||
catch (const Exception &e)
|
||||
{
|
||||
QMessageBox::critical(this, tr("Error"), e.cause());
|
||||
}
|
||||
updateButtons();
|
||||
try
|
||||
{
|
||||
m_profile->move(currentRow(), ComponentList::MoveUp);
|
||||
}
|
||||
catch (const Exception &e)
|
||||
{
|
||||
QMessageBox::critical(this, tr("Error"), e.cause());
|
||||
}
|
||||
updateButtons();
|
||||
}
|
||||
|
||||
void VersionPage::on_moveDownBtn_clicked()
|
||||
{
|
||||
try
|
||||
{
|
||||
m_profile->move(currentRow(), ComponentList::MoveDown);
|
||||
}
|
||||
catch (const Exception &e)
|
||||
{
|
||||
QMessageBox::critical(this, tr("Error"), e.cause());
|
||||
}
|
||||
updateButtons();
|
||||
try
|
||||
{
|
||||
m_profile->move(currentRow(), ComponentList::MoveDown);
|
||||
}
|
||||
catch (const Exception &e)
|
||||
{
|
||||
QMessageBox::critical(this, tr("Error"), e.cause());
|
||||
}
|
||||
updateButtons();
|
||||
}
|
||||
|
||||
void VersionPage::on_changeVersionBtn_clicked()
|
||||
{
|
||||
auto versionRow = currentRow();
|
||||
if(versionRow == -1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
auto patch = m_profile->getComponent(versionRow);
|
||||
auto name = patch->getName();
|
||||
auto list = patch->getVersionList();
|
||||
if(!list)
|
||||
{
|
||||
return;
|
||||
}
|
||||
auto uid = list->uid();
|
||||
// FIXME: this is a horrible HACK. Get version filtering information from the actual metadata...
|
||||
if(uid == "net.minecraftforge")
|
||||
{
|
||||
on_forgeBtn_clicked();
|
||||
return;
|
||||
}
|
||||
else if (uid == "com.mumfrey.liteloader")
|
||||
{
|
||||
on_liteloaderBtn_clicked();
|
||||
return;
|
||||
}
|
||||
VersionSelectDialog vselect(list.get(), tr("Change %1 version").arg(name), this);
|
||||
auto currentVersion = patch->getVersion();
|
||||
if(!currentVersion.isEmpty())
|
||||
{
|
||||
vselect.setCurrentVersion(currentVersion);
|
||||
}
|
||||
if (!vselect.exec() || !vselect.selectedVersion())
|
||||
return;
|
||||
auto versionRow = currentRow();
|
||||
if(versionRow == -1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
auto patch = m_profile->getComponent(versionRow);
|
||||
auto name = patch->getName();
|
||||
auto list = patch->getVersionList();
|
||||
if(!list)
|
||||
{
|
||||
return;
|
||||
}
|
||||
auto uid = list->uid();
|
||||
// FIXME: this is a horrible HACK. Get version filtering information from the actual metadata...
|
||||
if(uid == "net.minecraftforge")
|
||||
{
|
||||
on_forgeBtn_clicked();
|
||||
return;
|
||||
}
|
||||
else if (uid == "com.mumfrey.liteloader")
|
||||
{
|
||||
on_liteloaderBtn_clicked();
|
||||
return;
|
||||
}
|
||||
VersionSelectDialog vselect(list.get(), tr("Change %1 version").arg(name), this);
|
||||
auto currentVersion = patch->getVersion();
|
||||
if(!currentVersion.isEmpty())
|
||||
{
|
||||
vselect.setCurrentVersion(currentVersion);
|
||||
}
|
||||
if (!vselect.exec() || !vselect.selectedVersion())
|
||||
return;
|
||||
|
||||
qDebug() << "Change" << uid << "to" << vselect.selectedVersion()->descriptor();
|
||||
bool important = false;
|
||||
if(uid == "net.minecraft")
|
||||
{
|
||||
important = true;
|
||||
}
|
||||
m_profile->setComponentVersion(uid, vselect.selectedVersion()->descriptor(), important);
|
||||
m_profile->resolve(Net::Mode::Online);
|
||||
m_container->refreshContainer();
|
||||
qDebug() << "Change" << uid << "to" << vselect.selectedVersion()->descriptor();
|
||||
bool important = false;
|
||||
if(uid == "net.minecraft")
|
||||
{
|
||||
important = true;
|
||||
}
|
||||
m_profile->setComponentVersion(uid, vselect.selectedVersion()->descriptor(), important);
|
||||
m_profile->resolve(Net::Mode::Online);
|
||||
m_container->refreshContainer();
|
||||
}
|
||||
|
||||
void VersionPage::on_downloadBtn_clicked()
|
||||
{
|
||||
if (!MMC->accounts()->anyAccountIsValid())
|
||||
{
|
||||
CustomMessageBox::selectable(
|
||||
this, tr("Error"),
|
||||
tr("MultiMC cannot download Minecraft or update instances unless you have at least "
|
||||
"one account added.\nPlease add your Mojang or Minecraft account."),
|
||||
QMessageBox::Warning)->show();
|
||||
return;
|
||||
}
|
||||
if (!MMC->accounts()->anyAccountIsValid())
|
||||
{
|
||||
CustomMessageBox::selectable(
|
||||
this, tr("Error"),
|
||||
tr("MultiMC cannot download Minecraft or update instances unless you have at least "
|
||||
"one account added.\nPlease add your Mojang or Minecraft account."),
|
||||
QMessageBox::Warning)->show();
|
||||
return;
|
||||
}
|
||||
|
||||
auto updateTask = m_inst->createUpdateTask(Net::Mode::Online);
|
||||
if (!updateTask)
|
||||
{
|
||||
return;
|
||||
}
|
||||
ProgressDialog tDialog(this);
|
||||
connect(updateTask.get(), SIGNAL(failed(QString)), SLOT(onGameUpdateError(QString)));
|
||||
// FIXME: unused return value
|
||||
tDialog.execWithTask(updateTask.get());
|
||||
updateButtons();
|
||||
m_container->refreshContainer();
|
||||
auto updateTask = m_inst->createUpdateTask(Net::Mode::Online);
|
||||
if (!updateTask)
|
||||
{
|
||||
return;
|
||||
}
|
||||
ProgressDialog tDialog(this);
|
||||
connect(updateTask.get(), SIGNAL(failed(QString)), SLOT(onGameUpdateError(QString)));
|
||||
// FIXME: unused return value
|
||||
tDialog.execWithTask(updateTask.get());
|
||||
updateButtons();
|
||||
m_container->refreshContainer();
|
||||
}
|
||||
|
||||
void VersionPage::on_forgeBtn_clicked()
|
||||
{
|
||||
auto vlist = ENV.metadataIndex()->get("net.minecraftforge");
|
||||
if(!vlist)
|
||||
{
|
||||
return;
|
||||
}
|
||||
VersionSelectDialog vselect(vlist.get(), tr("Select Forge version"), this);
|
||||
vselect.setExactFilter(BaseVersionList::ParentVersionRole, m_profile->getComponentVersion("net.minecraft"));
|
||||
vselect.setEmptyString(tr("No Forge versions are currently available for Minecraft ") + m_profile->getComponentVersion("net.minecraft"));
|
||||
vselect.setEmptyErrorString(tr("Couldn't load or download the Forge version lists!"));
|
||||
auto vlist = ENV.metadataIndex()->get("net.minecraftforge");
|
||||
if(!vlist)
|
||||
{
|
||||
return;
|
||||
}
|
||||
VersionSelectDialog vselect(vlist.get(), tr("Select Forge version"), this);
|
||||
vselect.setExactFilter(BaseVersionList::ParentVersionRole, m_profile->getComponentVersion("net.minecraft"));
|
||||
vselect.setEmptyString(tr("No Forge versions are currently available for Minecraft ") + m_profile->getComponentVersion("net.minecraft"));
|
||||
vselect.setEmptyErrorString(tr("Couldn't load or download the Forge version lists!"));
|
||||
|
||||
auto currentVersion = m_profile->getComponentVersion("net.minecraftforge");
|
||||
if(!currentVersion.isEmpty())
|
||||
{
|
||||
vselect.setCurrentVersion(currentVersion);
|
||||
}
|
||||
auto currentVersion = m_profile->getComponentVersion("net.minecraftforge");
|
||||
if(!currentVersion.isEmpty())
|
||||
{
|
||||
vselect.setCurrentVersion(currentVersion);
|
||||
}
|
||||
|
||||
if (vselect.exec() && vselect.selectedVersion())
|
||||
{
|
||||
auto vsn = vselect.selectedVersion();
|
||||
m_profile->setComponentVersion("net.minecraftforge", vsn->descriptor());
|
||||
m_profile->resolve(Net::Mode::Online);
|
||||
// m_profile->installVersion();
|
||||
preselect(m_profile->rowCount(QModelIndex())-1);
|
||||
m_container->refreshContainer();
|
||||
}
|
||||
if (vselect.exec() && vselect.selectedVersion())
|
||||
{
|
||||
auto vsn = vselect.selectedVersion();
|
||||
m_profile->setComponentVersion("net.minecraftforge", vsn->descriptor());
|
||||
m_profile->resolve(Net::Mode::Online);
|
||||
// m_profile->installVersion();
|
||||
preselect(m_profile->rowCount(QModelIndex())-1);
|
||||
m_container->refreshContainer();
|
||||
}
|
||||
}
|
||||
|
||||
void VersionPage::on_addEmptyBtn_clicked()
|
||||
{
|
||||
NewComponentDialog compdialog(QString(), QString(), this);
|
||||
QStringList blacklist;
|
||||
for(int i = 0; i < m_profile->rowCount(); i++)
|
||||
{
|
||||
auto comp = m_profile->getComponent(i);
|
||||
blacklist.push_back(comp->getID());
|
||||
}
|
||||
compdialog.setBlacklist(blacklist);
|
||||
if (compdialog.exec())
|
||||
{
|
||||
qDebug() << "name:" << compdialog.name();
|
||||
qDebug() << "uid:" << compdialog.uid();
|
||||
m_profile->installEmpty(compdialog.uid(), compdialog.name());
|
||||
}
|
||||
NewComponentDialog compdialog(QString(), QString(), this);
|
||||
QStringList blacklist;
|
||||
for(int i = 0; i < m_profile->rowCount(); i++)
|
||||
{
|
||||
auto comp = m_profile->getComponent(i);
|
||||
blacklist.push_back(comp->getID());
|
||||
}
|
||||
compdialog.setBlacklist(blacklist);
|
||||
if (compdialog.exec())
|
||||
{
|
||||
qDebug() << "name:" << compdialog.name();
|
||||
qDebug() << "uid:" << compdialog.uid();
|
||||
m_profile->installEmpty(compdialog.uid(), compdialog.name());
|
||||
}
|
||||
}
|
||||
|
||||
void VersionPage::on_liteloaderBtn_clicked()
|
||||
{
|
||||
auto vlist = ENV.metadataIndex()->get("com.mumfrey.liteloader");
|
||||
if(!vlist)
|
||||
{
|
||||
return;
|
||||
}
|
||||
VersionSelectDialog vselect(vlist.get(), tr("Select LiteLoader version"), this);
|
||||
vselect.setExactFilter(BaseVersionList::ParentVersionRole, m_profile->getComponentVersion("net.minecraft"));
|
||||
vselect.setEmptyString(tr("No LiteLoader versions are currently available for Minecraft ") + m_profile->getComponentVersion("net.minecraft"));
|
||||
vselect.setEmptyErrorString(tr("Couldn't load or download the LiteLoader version lists!"));
|
||||
auto vlist = ENV.metadataIndex()->get("com.mumfrey.liteloader");
|
||||
if(!vlist)
|
||||
{
|
||||
return;
|
||||
}
|
||||
VersionSelectDialog vselect(vlist.get(), tr("Select LiteLoader version"), this);
|
||||
vselect.setExactFilter(BaseVersionList::ParentVersionRole, m_profile->getComponentVersion("net.minecraft"));
|
||||
vselect.setEmptyString(tr("No LiteLoader versions are currently available for Minecraft ") + m_profile->getComponentVersion("net.minecraft"));
|
||||
vselect.setEmptyErrorString(tr("Couldn't load or download the LiteLoader version lists!"));
|
||||
|
||||
auto currentVersion = m_profile->getComponentVersion("com.mumfrey.liteloader");
|
||||
if(!currentVersion.isEmpty())
|
||||
{
|
||||
vselect.setCurrentVersion(currentVersion);
|
||||
}
|
||||
auto currentVersion = m_profile->getComponentVersion("com.mumfrey.liteloader");
|
||||
if(!currentVersion.isEmpty())
|
||||
{
|
||||
vselect.setCurrentVersion(currentVersion);
|
||||
}
|
||||
|
||||
if (vselect.exec() && vselect.selectedVersion())
|
||||
{
|
||||
auto vsn = vselect.selectedVersion();
|
||||
m_profile->setComponentVersion("com.mumfrey.liteloader", vsn->descriptor());
|
||||
m_profile->resolve(Net::Mode::Online);
|
||||
// m_profile->installVersion(vselect.selectedVersion());
|
||||
preselect(m_profile->rowCount(QModelIndex())-1);
|
||||
m_container->refreshContainer();
|
||||
}
|
||||
if (vselect.exec() && vselect.selectedVersion())
|
||||
{
|
||||
auto vsn = vselect.selectedVersion();
|
||||
m_profile->setComponentVersion("com.mumfrey.liteloader", vsn->descriptor());
|
||||
m_profile->resolve(Net::Mode::Online);
|
||||
// m_profile->installVersion(vselect.selectedVersion());
|
||||
preselect(m_profile->rowCount(QModelIndex())-1);
|
||||
m_container->refreshContainer();
|
||||
}
|
||||
}
|
||||
|
||||
void VersionPage::versionCurrent(const QModelIndex ¤t, const QModelIndex &previous)
|
||||
{
|
||||
currentIdx = current.row();
|
||||
updateButtons(currentIdx);
|
||||
currentIdx = current.row();
|
||||
updateButtons(currentIdx);
|
||||
}
|
||||
|
||||
void VersionPage::preselect(int row)
|
||||
{
|
||||
if(row < 0)
|
||||
{
|
||||
row = 0;
|
||||
}
|
||||
if(row >= m_profile->rowCount(QModelIndex()))
|
||||
{
|
||||
row = m_profile->rowCount(QModelIndex()) - 1;
|
||||
}
|
||||
if(row < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
auto model_index = m_profile->index(row);
|
||||
ui->packageView->selectionModel()->select(model_index, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows);
|
||||
updateButtons(row);
|
||||
if(row < 0)
|
||||
{
|
||||
row = 0;
|
||||
}
|
||||
if(row >= m_profile->rowCount(QModelIndex()))
|
||||
{
|
||||
row = m_profile->rowCount(QModelIndex()) - 1;
|
||||
}
|
||||
if(row < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
auto model_index = m_profile->index(row);
|
||||
ui->packageView->selectionModel()->select(model_index, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows);
|
||||
updateButtons(row);
|
||||
}
|
||||
|
||||
void VersionPage::updateButtons(int row)
|
||||
{
|
||||
if(row == -1)
|
||||
row = currentRow();
|
||||
auto patch = m_profile->getComponent(row);
|
||||
if (!patch)
|
||||
{
|
||||
ui->removeBtn->setDisabled(true);
|
||||
ui->moveDownBtn->setDisabled(true);
|
||||
ui->moveUpBtn->setDisabled(true);
|
||||
ui->changeVersionBtn->setDisabled(true);
|
||||
ui->editBtn->setDisabled(true);
|
||||
ui->customizeBtn->setDisabled(true);
|
||||
ui->revertBtn->setDisabled(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->removeBtn->setEnabled(patch->isRemovable());
|
||||
ui->moveDownBtn->setEnabled(patch->isMoveable());
|
||||
ui->moveUpBtn->setEnabled(patch->isMoveable());
|
||||
ui->changeVersionBtn->setEnabled(patch->isVersionChangeable());
|
||||
ui->editBtn->setEnabled(patch->isCustom());
|
||||
ui->customizeBtn->setEnabled(patch->isCustomizable());
|
||||
ui->revertBtn->setEnabled(patch->isRevertible());
|
||||
}
|
||||
if(row == -1)
|
||||
row = currentRow();
|
||||
auto patch = m_profile->getComponent(row);
|
||||
if (!patch)
|
||||
{
|
||||
ui->removeBtn->setDisabled(true);
|
||||
ui->moveDownBtn->setDisabled(true);
|
||||
ui->moveUpBtn->setDisabled(true);
|
||||
ui->changeVersionBtn->setDisabled(true);
|
||||
ui->editBtn->setDisabled(true);
|
||||
ui->customizeBtn->setDisabled(true);
|
||||
ui->revertBtn->setDisabled(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->removeBtn->setEnabled(patch->isRemovable());
|
||||
ui->moveDownBtn->setEnabled(patch->isMoveable());
|
||||
ui->moveUpBtn->setEnabled(patch->isMoveable());
|
||||
ui->changeVersionBtn->setEnabled(patch->isVersionChangeable());
|
||||
ui->editBtn->setEnabled(patch->isCustom());
|
||||
ui->customizeBtn->setEnabled(patch->isCustomizable());
|
||||
ui->revertBtn->setEnabled(patch->isRevertible());
|
||||
}
|
||||
}
|
||||
|
||||
void VersionPage::onGameUpdateError(QString error)
|
||||
{
|
||||
CustomMessageBox::selectable(this, tr("Error updating instance"), error,
|
||||
QMessageBox::Warning)->show();
|
||||
CustomMessageBox::selectable(this, tr("Error updating instance"), error,
|
||||
QMessageBox::Warning)->show();
|
||||
}
|
||||
|
||||
Component * VersionPage::current()
|
||||
{
|
||||
auto row = currentRow();
|
||||
if(row < 0)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
return m_profile->getComponent(row);
|
||||
auto row = currentRow();
|
||||
if(row < 0)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
return m_profile->getComponent(row);
|
||||
}
|
||||
|
||||
int VersionPage::currentRow()
|
||||
{
|
||||
if (ui->packageView->selectionModel()->selectedRows().isEmpty())
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return ui->packageView->selectionModel()->selectedRows().first().row();
|
||||
if (ui->packageView->selectionModel()->selectedRows().isEmpty())
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return ui->packageView->selectionModel()->selectedRows().first().row();
|
||||
}
|
||||
|
||||
void VersionPage::on_customizeBtn_clicked()
|
||||
{
|
||||
auto version = currentRow();
|
||||
if(version == -1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
auto patch = m_profile->getComponent(version);
|
||||
if(!patch->getVersionFile())
|
||||
{
|
||||
// TODO: wait for the update task to finish here...
|
||||
return;
|
||||
}
|
||||
if(!m_profile->customize(version))
|
||||
{
|
||||
// TODO: some error box here
|
||||
}
|
||||
updateButtons();
|
||||
preselect(currentIdx);
|
||||
auto version = currentRow();
|
||||
if(version == -1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
auto patch = m_profile->getComponent(version);
|
||||
if(!patch->getVersionFile())
|
||||
{
|
||||
// TODO: wait for the update task to finish here...
|
||||
return;
|
||||
}
|
||||
if(!m_profile->customize(version))
|
||||
{
|
||||
// TODO: some error box here
|
||||
}
|
||||
updateButtons();
|
||||
preselect(currentIdx);
|
||||
}
|
||||
|
||||
void VersionPage::on_editBtn_clicked()
|
||||
{
|
||||
auto version = current();
|
||||
if(!version)
|
||||
{
|
||||
return;
|
||||
}
|
||||
auto filename = version->getFilename();
|
||||
if(!QFileInfo::exists(filename))
|
||||
{
|
||||
qWarning() << "file" << filename << "can't be opened for editing, doesn't exist!";
|
||||
return;
|
||||
}
|
||||
MMC->openJsonEditor(filename);
|
||||
auto version = current();
|
||||
if(!version)
|
||||
{
|
||||
return;
|
||||
}
|
||||
auto filename = version->getFilename();
|
||||
if(!QFileInfo::exists(filename))
|
||||
{
|
||||
qWarning() << "file" << filename << "can't be opened for editing, doesn't exist!";
|
||||
return;
|
||||
}
|
||||
MMC->openJsonEditor(filename);
|
||||
}
|
||||
|
||||
void VersionPage::on_revertBtn_clicked()
|
||||
{
|
||||
auto version = currentRow();
|
||||
if(version == -1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if(!m_profile->revertToBase(version))
|
||||
{
|
||||
// TODO: some error box here
|
||||
}
|
||||
updateButtons();
|
||||
preselect(currentIdx);
|
||||
m_container->refreshContainer();
|
||||
auto version = currentRow();
|
||||
if(version == -1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if(!m_profile->revertToBase(version))
|
||||
{
|
||||
// TODO: some error box here
|
||||
}
|
||||
updateButtons();
|
||||
preselect(currentIdx);
|
||||
m_container->refreshContainer();
|
||||
}
|
||||
|
||||
#include "VersionPage.moc"
|
||||
|
@ -28,68 +28,68 @@ class VersionPage;
|
||||
|
||||
class VersionPage : public QWidget, public BasePage
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit VersionPage(MinecraftInstance *inst, QWidget *parent = 0);
|
||||
virtual ~VersionPage();
|
||||
virtual QString displayName() const override
|
||||
{
|
||||
return tr("Version");
|
||||
}
|
||||
virtual QIcon icon() const override;
|
||||
virtual QString id() const override
|
||||
{
|
||||
return "version";
|
||||
}
|
||||
virtual QString helpPage() const override
|
||||
{
|
||||
return "Instance-Version";
|
||||
}
|
||||
virtual bool shouldDisplay() const override;
|
||||
explicit VersionPage(MinecraftInstance *inst, QWidget *parent = 0);
|
||||
virtual ~VersionPage();
|
||||
virtual QString displayName() const override
|
||||
{
|
||||
return tr("Version");
|
||||
}
|
||||
virtual QIcon icon() const override;
|
||||
virtual QString id() const override
|
||||
{
|
||||
return "version";
|
||||
}
|
||||
virtual QString helpPage() const override
|
||||
{
|
||||
return "Instance-Version";
|
||||
}
|
||||
virtual bool shouldDisplay() const override;
|
||||
|
||||
private slots:
|
||||
void on_forgeBtn_clicked();
|
||||
void on_addEmptyBtn_clicked();
|
||||
void on_liteloaderBtn_clicked();
|
||||
void on_reloadBtn_clicked();
|
||||
void on_removeBtn_clicked();
|
||||
void on_moveUpBtn_clicked();
|
||||
void on_moveDownBtn_clicked();
|
||||
void on_jarmodBtn_clicked();
|
||||
void on_jarBtn_clicked();
|
||||
void on_revertBtn_clicked();
|
||||
void on_editBtn_clicked();
|
||||
void on_modBtn_clicked();
|
||||
void on_customizeBtn_clicked();
|
||||
void on_downloadBtn_clicked();
|
||||
void on_forgeBtn_clicked();
|
||||
void on_addEmptyBtn_clicked();
|
||||
void on_liteloaderBtn_clicked();
|
||||
void on_reloadBtn_clicked();
|
||||
void on_removeBtn_clicked();
|
||||
void on_moveUpBtn_clicked();
|
||||
void on_moveDownBtn_clicked();
|
||||
void on_jarmodBtn_clicked();
|
||||
void on_jarBtn_clicked();
|
||||
void on_revertBtn_clicked();
|
||||
void on_editBtn_clicked();
|
||||
void on_modBtn_clicked();
|
||||
void on_customizeBtn_clicked();
|
||||
void on_downloadBtn_clicked();
|
||||
|
||||
void updateVersionControls();
|
||||
void disableVersionControls();
|
||||
void on_changeVersionBtn_clicked();
|
||||
void updateVersionControls();
|
||||
void disableVersionControls();
|
||||
void on_changeVersionBtn_clicked();
|
||||
|
||||
private:
|
||||
Component * current();
|
||||
int currentRow();
|
||||
void updateButtons(int row = -1);
|
||||
void preselect(int row = 0);
|
||||
int doUpdate();
|
||||
Component * current();
|
||||
int currentRow();
|
||||
void updateButtons(int row = -1);
|
||||
void preselect(int row = 0);
|
||||
int doUpdate();
|
||||
|
||||
protected:
|
||||
/// FIXME: this shouldn't be necessary!
|
||||
bool reloadComponentList();
|
||||
/// FIXME: this shouldn't be necessary!
|
||||
bool reloadComponentList();
|
||||
|
||||
private:
|
||||
Ui::VersionPage *ui;
|
||||
std::shared_ptr<ComponentList> m_profile;
|
||||
MinecraftInstance *m_inst;
|
||||
int currentIdx = 0;
|
||||
Ui::VersionPage *ui;
|
||||
std::shared_ptr<ComponentList> m_profile;
|
||||
MinecraftInstance *m_inst;
|
||||
int currentIdx = 0;
|
||||
|
||||
public slots:
|
||||
void versionCurrent(const QModelIndex ¤t, const QModelIndex &previous);
|
||||
void versionCurrent(const QModelIndex ¤t, const QModelIndex &previous);
|
||||
|
||||
private slots:
|
||||
void onGameUpdateError(QString error);
|
||||
void packageCurrent(const QModelIndex ¤t, const QModelIndex &previous);
|
||||
void onGameUpdateError(QString error);
|
||||
void packageCurrent(const QModelIndex ¤t, const QModelIndex &previous);
|
||||
|
||||
};
|
||||
|
@ -32,299 +32,299 @@
|
||||
#include <FileSystem.h>
|
||||
|
||||
WorldListPage::WorldListPage(BaseInstance *inst, std::shared_ptr<WorldList> worlds, QString id,
|
||||
QString iconName, QString displayName, QString helpPage,
|
||||
QWidget *parent)
|
||||
: QWidget(parent), m_inst(inst), ui(new Ui::WorldListPage), m_worlds(worlds), m_iconName(iconName), m_id(id), m_displayName(displayName), m_helpName(helpPage)
|
||||
QString iconName, QString displayName, QString helpPage,
|
||||
QWidget *parent)
|
||||
: QWidget(parent), m_inst(inst), ui(new Ui::WorldListPage), m_worlds(worlds), m_iconName(iconName), m_id(id), m_displayName(displayName), m_helpName(helpPage)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->tabWidget->tabBar()->hide();
|
||||
QSortFilterProxyModel * proxy = new QSortFilterProxyModel(this);
|
||||
proxy->setSortCaseSensitivity(Qt::CaseInsensitive);
|
||||
proxy->setSourceModel(m_worlds.get());
|
||||
ui->worldTreeView->setSortingEnabled(true);
|
||||
ui->worldTreeView->setModel(proxy);
|
||||
ui->worldTreeView->installEventFilter(this);
|
||||
ui->setupUi(this);
|
||||
ui->tabWidget->tabBar()->hide();
|
||||
QSortFilterProxyModel * proxy = new QSortFilterProxyModel(this);
|
||||
proxy->setSortCaseSensitivity(Qt::CaseInsensitive);
|
||||
proxy->setSourceModel(m_worlds.get());
|
||||
ui->worldTreeView->setSortingEnabled(true);
|
||||
ui->worldTreeView->setModel(proxy);
|
||||
ui->worldTreeView->installEventFilter(this);
|
||||
|
||||
auto head = ui->worldTreeView->header();
|
||||
auto head = ui->worldTreeView->header();
|
||||
|
||||
head->setSectionResizeMode(0, QHeaderView::Stretch);
|
||||
head->setSectionResizeMode(1, QHeaderView::ResizeToContents);
|
||||
connect(ui->worldTreeView->selectionModel(),
|
||||
SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)), this,
|
||||
SLOT(worldChanged(const QModelIndex &, const QModelIndex &)));
|
||||
worldChanged(QModelIndex(), QModelIndex());
|
||||
head->setSectionResizeMode(0, QHeaderView::Stretch);
|
||||
head->setSectionResizeMode(1, QHeaderView::ResizeToContents);
|
||||
connect(ui->worldTreeView->selectionModel(),
|
||||
SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)), this,
|
||||
SLOT(worldChanged(const QModelIndex &, const QModelIndex &)));
|
||||
worldChanged(QModelIndex(), QModelIndex());
|
||||
}
|
||||
|
||||
void WorldListPage::openedImpl()
|
||||
{
|
||||
m_worlds->startWatching();
|
||||
m_worlds->startWatching();
|
||||
}
|
||||
|
||||
void WorldListPage::closedImpl()
|
||||
{
|
||||
m_worlds->stopWatching();
|
||||
m_worlds->stopWatching();
|
||||
}
|
||||
|
||||
WorldListPage::~WorldListPage()
|
||||
{
|
||||
m_worlds->stopWatching();
|
||||
delete ui;
|
||||
m_worlds->stopWatching();
|
||||
delete ui;
|
||||
}
|
||||
|
||||
bool WorldListPage::shouldDisplay() const
|
||||
{
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WorldListPage::worldListFilter(QKeyEvent *keyEvent)
|
||||
{
|
||||
switch (keyEvent->key())
|
||||
{
|
||||
case Qt::Key_Delete:
|
||||
on_rmWorldBtn_clicked();
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return QWidget::eventFilter(ui->worldTreeView, keyEvent);
|
||||
switch (keyEvent->key())
|
||||
{
|
||||
case Qt::Key_Delete:
|
||||
on_rmWorldBtn_clicked();
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return QWidget::eventFilter(ui->worldTreeView, keyEvent);
|
||||
}
|
||||
|
||||
bool WorldListPage::eventFilter(QObject *obj, QEvent *ev)
|
||||
{
|
||||
if (ev->type() != QEvent::KeyPress)
|
||||
{
|
||||
return QWidget::eventFilter(obj, ev);
|
||||
}
|
||||
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(ev);
|
||||
if (obj == ui->worldTreeView)
|
||||
return worldListFilter(keyEvent);
|
||||
return QWidget::eventFilter(obj, ev);
|
||||
if (ev->type() != QEvent::KeyPress)
|
||||
{
|
||||
return QWidget::eventFilter(obj, ev);
|
||||
}
|
||||
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(ev);
|
||||
if (obj == ui->worldTreeView)
|
||||
return worldListFilter(keyEvent);
|
||||
return QWidget::eventFilter(obj, ev);
|
||||
}
|
||||
|
||||
void WorldListPage::on_rmWorldBtn_clicked()
|
||||
{
|
||||
auto proxiedIndex = getSelectedWorld();
|
||||
auto proxiedIndex = getSelectedWorld();
|
||||
|
||||
if(!proxiedIndex.isValid())
|
||||
return;
|
||||
if(!proxiedIndex.isValid())
|
||||
return;
|
||||
|
||||
auto result = QMessageBox::question(this,
|
||||
tr("Are you sure?"),
|
||||
tr("This will remove the selected world permenantly.\n"
|
||||
"The world will be gone forever (A LONG TIME).\n"
|
||||
"\n"
|
||||
"Do you want to continue?"));
|
||||
if(result != QMessageBox::Yes)
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_worlds->stopWatching();
|
||||
m_worlds->deleteWorld(proxiedIndex.row());
|
||||
m_worlds->startWatching();
|
||||
auto result = QMessageBox::question(this,
|
||||
tr("Are you sure?"),
|
||||
tr("This will remove the selected world permenantly.\n"
|
||||
"The world will be gone forever (A LONG TIME).\n"
|
||||
"\n"
|
||||
"Do you want to continue?"));
|
||||
if(result != QMessageBox::Yes)
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_worlds->stopWatching();
|
||||
m_worlds->deleteWorld(proxiedIndex.row());
|
||||
m_worlds->startWatching();
|
||||
}
|
||||
|
||||
void WorldListPage::on_viewFolderBtn_clicked()
|
||||
{
|
||||
DesktopServices::openDirectory(m_worlds->dir().absolutePath(), true);
|
||||
DesktopServices::openDirectory(m_worlds->dir().absolutePath(), true);
|
||||
}
|
||||
|
||||
QModelIndex WorldListPage::getSelectedWorld()
|
||||
{
|
||||
auto index = ui->worldTreeView->selectionModel()->currentIndex();
|
||||
auto index = ui->worldTreeView->selectionModel()->currentIndex();
|
||||
|
||||
auto proxy = (QSortFilterProxyModel *) ui->worldTreeView->model();
|
||||
return proxy->mapToSource(index);
|
||||
auto proxy = (QSortFilterProxyModel *) ui->worldTreeView->model();
|
||||
return proxy->mapToSource(index);
|
||||
}
|
||||
|
||||
void WorldListPage::on_copySeedBtn_clicked()
|
||||
{
|
||||
QModelIndex index = getSelectedWorld();
|
||||
QModelIndex index = getSelectedWorld();
|
||||
|
||||
if (!index.isValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
int64_t seed = m_worlds->data(index, WorldList::SeedRole).toLongLong();
|
||||
MMC->clipboard()->setText(QString::number(seed));
|
||||
if (!index.isValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
int64_t seed = m_worlds->data(index, WorldList::SeedRole).toLongLong();
|
||||
MMC->clipboard()->setText(QString::number(seed));
|
||||
}
|
||||
|
||||
void WorldListPage::on_mcEditBtn_clicked()
|
||||
{
|
||||
if(m_mceditStarting)
|
||||
return;
|
||||
if(m_mceditStarting)
|
||||
return;
|
||||
|
||||
auto mcedit = MMC->mcedit();
|
||||
auto mcedit = MMC->mcedit();
|
||||
|
||||
const QString mceditPath = mcedit->path();
|
||||
const QString mceditPath = mcedit->path();
|
||||
|
||||
QModelIndex index = getSelectedWorld();
|
||||
QModelIndex index = getSelectedWorld();
|
||||
|
||||
if (!index.isValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!index.isValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(!worldSafetyNagQuestion())
|
||||
return;
|
||||
if(!worldSafetyNagQuestion())
|
||||
return;
|
||||
|
||||
auto fullPath = m_worlds->data(index, WorldList::FolderRole).toString();
|
||||
auto fullPath = m_worlds->data(index, WorldList::FolderRole).toString();
|
||||
|
||||
auto program = mcedit->getProgramPath();
|
||||
if(program.size())
|
||||
{
|
||||
auto program = mcedit->getProgramPath();
|
||||
if(program.size())
|
||||
{
|
||||
#ifdef Q_OS_WIN32
|
||||
if(!QProcess::startDetached(program, {fullPath}, mceditPath))
|
||||
{
|
||||
mceditError();
|
||||
}
|
||||
if(!QProcess::startDetached(program, {fullPath}, mceditPath))
|
||||
{
|
||||
mceditError();
|
||||
}
|
||||
#else
|
||||
m_mceditProcess.reset(new LoggedProcess());
|
||||
m_mceditProcess->setDetachable(true);
|
||||
connect(m_mceditProcess.get(), &LoggedProcess::stateChanged, this, &WorldListPage::mceditState);
|
||||
m_mceditProcess->start(program, {fullPath});
|
||||
m_mceditProcess->setWorkingDirectory(mceditPath);
|
||||
m_mceditStarting = true;
|
||||
m_mceditProcess.reset(new LoggedProcess());
|
||||
m_mceditProcess->setDetachable(true);
|
||||
connect(m_mceditProcess.get(), &LoggedProcess::stateChanged, this, &WorldListPage::mceditState);
|
||||
m_mceditProcess->start(program, {fullPath});
|
||||
m_mceditProcess->setWorkingDirectory(mceditPath);
|
||||
m_mceditStarting = true;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
QMessageBox::warning(
|
||||
this->parentWidget(),
|
||||
tr("No MCEdit found or set up!"),
|
||||
tr("You do not have MCEdit set up or it was moved.\nYou can set it up in the global settings.")
|
||||
);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
QMessageBox::warning(
|
||||
this->parentWidget(),
|
||||
tr("No MCEdit found or set up!"),
|
||||
tr("You do not have MCEdit set up or it was moved.\nYou can set it up in the global settings.")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void WorldListPage::mceditError()
|
||||
{
|
||||
QMessageBox::warning(
|
||||
this->parentWidget(),
|
||||
tr("MCEdit failed to start!"),
|
||||
tr("MCEdit failed to start.\nIt may be necessary to reinstall it.")
|
||||
);
|
||||
QMessageBox::warning(
|
||||
this->parentWidget(),
|
||||
tr("MCEdit failed to start!"),
|
||||
tr("MCEdit failed to start.\nIt may be necessary to reinstall it.")
|
||||
);
|
||||
}
|
||||
|
||||
void WorldListPage::mceditState(LoggedProcess::State state)
|
||||
{
|
||||
bool failed = false;
|
||||
switch(state)
|
||||
{
|
||||
case LoggedProcess::NotRunning:
|
||||
case LoggedProcess::Starting:
|
||||
return;
|
||||
case LoggedProcess::FailedToStart:
|
||||
case LoggedProcess::Crashed:
|
||||
case LoggedProcess::Aborted:
|
||||
{
|
||||
failed = true;
|
||||
}
|
||||
case LoggedProcess::Running:
|
||||
case LoggedProcess::Finished:
|
||||
{
|
||||
m_mceditStarting = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(failed)
|
||||
{
|
||||
mceditError();
|
||||
}
|
||||
bool failed = false;
|
||||
switch(state)
|
||||
{
|
||||
case LoggedProcess::NotRunning:
|
||||
case LoggedProcess::Starting:
|
||||
return;
|
||||
case LoggedProcess::FailedToStart:
|
||||
case LoggedProcess::Crashed:
|
||||
case LoggedProcess::Aborted:
|
||||
{
|
||||
failed = true;
|
||||
}
|
||||
case LoggedProcess::Running:
|
||||
case LoggedProcess::Finished:
|
||||
{
|
||||
m_mceditStarting = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(failed)
|
||||
{
|
||||
mceditError();
|
||||
}
|
||||
}
|
||||
|
||||
void WorldListPage::worldChanged(const QModelIndex ¤t, const QModelIndex &previous)
|
||||
{
|
||||
QModelIndex index = getSelectedWorld();
|
||||
bool enable = index.isValid();
|
||||
ui->copySeedBtn->setEnabled(enable);
|
||||
ui->mcEditBtn->setEnabled(enable);
|
||||
ui->rmWorldBtn->setEnabled(enable);
|
||||
ui->copyBtn->setEnabled(enable);
|
||||
ui->renameBtn->setEnabled(enable);
|
||||
QModelIndex index = getSelectedWorld();
|
||||
bool enable = index.isValid();
|
||||
ui->copySeedBtn->setEnabled(enable);
|
||||
ui->mcEditBtn->setEnabled(enable);
|
||||
ui->rmWorldBtn->setEnabled(enable);
|
||||
ui->copyBtn->setEnabled(enable);
|
||||
ui->renameBtn->setEnabled(enable);
|
||||
}
|
||||
|
||||
void WorldListPage::on_addBtn_clicked()
|
||||
{
|
||||
auto list = GuiUtil::BrowseForFiles(
|
||||
m_helpName,
|
||||
tr("Select a Minecraft world zip"),
|
||||
tr("Minecraft World Zip File (*.zip)"), QString(), this->parentWidget());
|
||||
if (!list.empty())
|
||||
{
|
||||
m_worlds->stopWatching();
|
||||
for (auto filename : list)
|
||||
{
|
||||
m_worlds->installWorld(QFileInfo(filename));
|
||||
}
|
||||
m_worlds->startWatching();
|
||||
}
|
||||
auto list = GuiUtil::BrowseForFiles(
|
||||
m_helpName,
|
||||
tr("Select a Minecraft world zip"),
|
||||
tr("Minecraft World Zip File (*.zip)"), QString(), this->parentWidget());
|
||||
if (!list.empty())
|
||||
{
|
||||
m_worlds->stopWatching();
|
||||
for (auto filename : list)
|
||||
{
|
||||
m_worlds->installWorld(QFileInfo(filename));
|
||||
}
|
||||
m_worlds->startWatching();
|
||||
}
|
||||
}
|
||||
|
||||
bool WorldListPage::isWorldSafe(QModelIndex)
|
||||
{
|
||||
return !m_inst->isRunning();
|
||||
return !m_inst->isRunning();
|
||||
}
|
||||
|
||||
bool WorldListPage::worldSafetyNagQuestion()
|
||||
{
|
||||
if(!isWorldSafe(getSelectedWorld()))
|
||||
{
|
||||
auto result = QMessageBox::question(this, tr("Copy World"), tr("Changing a world while Minecraft is running is potentially unsafe.\nDo you wish to proceed?"));
|
||||
if(result == QMessageBox::No)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
if(!isWorldSafe(getSelectedWorld()))
|
||||
{
|
||||
auto result = QMessageBox::question(this, tr("Copy World"), tr("Changing a world while Minecraft is running is potentially unsafe.\nDo you wish to proceed?"));
|
||||
if(result == QMessageBox::No)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void WorldListPage::on_copyBtn_clicked()
|
||||
{
|
||||
QModelIndex index = getSelectedWorld();
|
||||
if (!index.isValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
QModelIndex index = getSelectedWorld();
|
||||
if (!index.isValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(!worldSafetyNagQuestion())
|
||||
return;
|
||||
if(!worldSafetyNagQuestion())
|
||||
return;
|
||||
|
||||
auto worldVariant = m_worlds->data(index, WorldList::ObjectRole);
|
||||
auto world = (World *) worldVariant.value<void *>();
|
||||
bool ok = false;
|
||||
QString name = QInputDialog::getText(this, tr("World name"), tr("Enter a new name for the copy."), QLineEdit::Normal, world->name(), &ok);
|
||||
auto worldVariant = m_worlds->data(index, WorldList::ObjectRole);
|
||||
auto world = (World *) worldVariant.value<void *>();
|
||||
bool ok = false;
|
||||
QString name = QInputDialog::getText(this, tr("World name"), tr("Enter a new name for the copy."), QLineEdit::Normal, world->name(), &ok);
|
||||
|
||||
if (ok && name.length() > 0)
|
||||
{
|
||||
world->install(m_worlds->dir().absolutePath(), name);
|
||||
}
|
||||
if (ok && name.length() > 0)
|
||||
{
|
||||
world->install(m_worlds->dir().absolutePath(), name);
|
||||
}
|
||||
}
|
||||
|
||||
void WorldListPage::on_renameBtn_clicked()
|
||||
{
|
||||
QModelIndex index = getSelectedWorld();
|
||||
if (!index.isValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
QModelIndex index = getSelectedWorld();
|
||||
if (!index.isValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(!worldSafetyNagQuestion())
|
||||
return;
|
||||
if(!worldSafetyNagQuestion())
|
||||
return;
|
||||
|
||||
auto worldVariant = m_worlds->data(index, WorldList::ObjectRole);
|
||||
auto world = (World *) worldVariant.value<void *>();
|
||||
auto worldVariant = m_worlds->data(index, WorldList::ObjectRole);
|
||||
auto world = (World *) worldVariant.value<void *>();
|
||||
|
||||
bool ok = false;
|
||||
QString name = QInputDialog::getText(this, tr("World name"), tr("Enter a new world name."), QLineEdit::Normal, world->name(), &ok);
|
||||
bool ok = false;
|
||||
QString name = QInputDialog::getText(this, tr("World name"), tr("Enter a new world name."), QLineEdit::Normal, world->name(), &ok);
|
||||
|
||||
if (ok && name.length() > 0)
|
||||
{
|
||||
world->rename(name);
|
||||
}
|
||||
if (ok && name.length() > 0)
|
||||
{
|
||||
world->rename(name);
|
||||
}
|
||||
}
|
||||
|
||||
void WorldListPage::on_refreshBtn_clicked()
|
||||
{
|
||||
m_worlds->update();
|
||||
m_worlds->update();
|
||||
}
|
||||
|
@ -30,67 +30,67 @@ class WorldListPage;
|
||||
|
||||
class WorldListPage : public QWidget, public BasePage
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit WorldListPage(BaseInstance *inst, std::shared_ptr<WorldList> worlds, QString id,
|
||||
QString iconName, QString displayName, QString helpPage = "",
|
||||
QWidget *parent = 0);
|
||||
virtual ~WorldListPage();
|
||||
explicit WorldListPage(BaseInstance *inst, std::shared_ptr<WorldList> worlds, QString id,
|
||||
QString iconName, QString displayName, QString helpPage = "",
|
||||
QWidget *parent = 0);
|
||||
virtual ~WorldListPage();
|
||||
|
||||
virtual QString displayName() const override
|
||||
{
|
||||
return m_displayName;
|
||||
}
|
||||
virtual QIcon icon() const override
|
||||
{
|
||||
return MMC->getThemedIcon(m_iconName);
|
||||
}
|
||||
virtual QString id() const override
|
||||
{
|
||||
return m_id;
|
||||
}
|
||||
virtual QString helpPage() const override
|
||||
{
|
||||
return m_helpName;
|
||||
}
|
||||
virtual bool shouldDisplay() const override;
|
||||
virtual QString displayName() const override
|
||||
{
|
||||
return m_displayName;
|
||||
}
|
||||
virtual QIcon icon() const override
|
||||
{
|
||||
return MMC->getThemedIcon(m_iconName);
|
||||
}
|
||||
virtual QString id() const override
|
||||
{
|
||||
return m_id;
|
||||
}
|
||||
virtual QString helpPage() const override
|
||||
{
|
||||
return m_helpName;
|
||||
}
|
||||
virtual bool shouldDisplay() const override;
|
||||
|
||||
virtual void openedImpl() override;
|
||||
virtual void closedImpl() override;
|
||||
virtual void openedImpl() override;
|
||||
virtual void closedImpl() override;
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *obj, QEvent *ev) override;
|
||||
bool worldListFilter(QKeyEvent *ev);
|
||||
bool eventFilter(QObject *obj, QEvent *ev) override;
|
||||
bool worldListFilter(QKeyEvent *ev);
|
||||
|
||||
protected:
|
||||
BaseInstance *m_inst;
|
||||
BaseInstance *m_inst;
|
||||
|
||||
private:
|
||||
QModelIndex getSelectedWorld();
|
||||
bool isWorldSafe(QModelIndex index);
|
||||
bool worldSafetyNagQuestion();
|
||||
void mceditError();
|
||||
QModelIndex getSelectedWorld();
|
||||
bool isWorldSafe(QModelIndex index);
|
||||
bool worldSafetyNagQuestion();
|
||||
void mceditError();
|
||||
|
||||
private:
|
||||
Ui::WorldListPage *ui;
|
||||
std::shared_ptr<WorldList> m_worlds;
|
||||
unique_qobject_ptr<LoggedProcess> m_mceditProcess;
|
||||
bool m_mceditStarting = false;
|
||||
QString m_iconName;
|
||||
QString m_id;
|
||||
QString m_displayName;
|
||||
QString m_helpName;
|
||||
Ui::WorldListPage *ui;
|
||||
std::shared_ptr<WorldList> m_worlds;
|
||||
unique_qobject_ptr<LoggedProcess> m_mceditProcess;
|
||||
bool m_mceditStarting = false;
|
||||
QString m_iconName;
|
||||
QString m_id;
|
||||
QString m_displayName;
|
||||
QString m_helpName;
|
||||
|
||||
private slots:
|
||||
void on_copySeedBtn_clicked();
|
||||
void on_mcEditBtn_clicked();
|
||||
void on_rmWorldBtn_clicked();
|
||||
void on_addBtn_clicked();
|
||||
void on_copyBtn_clicked();
|
||||
void on_renameBtn_clicked();
|
||||
void on_refreshBtn_clicked();
|
||||
void on_viewFolderBtn_clicked();
|
||||
void worldChanged(const QModelIndex ¤t, const QModelIndex &previous);
|
||||
void mceditState(LoggedProcess::State state);
|
||||
void on_copySeedBtn_clicked();
|
||||
void on_mcEditBtn_clicked();
|
||||
void on_rmWorldBtn_clicked();
|
||||
void on_addBtn_clicked();
|
||||
void on_copyBtn_clicked();
|
||||
void on_renameBtn_clicked();
|
||||
void on_refreshBtn_clicked();
|
||||
void on_viewFolderBtn_clicked();
|
||||
void worldChanged(const QModelIndex ¤t, const QModelIndex &previous);
|
||||
void mceditState(LoggedProcess::State state);
|
||||
};
|
||||
|
Reference in New Issue
Block a user