Skip to content

Commit

Permalink
Merge pull request PrismLauncher#618 from TheKodeToad/safer-destructi…
Browse files Browse the repository at this point in the history
…ve-actions

Fixes PolyMC/PolyMC#948
  • Loading branch information
Scrumplex committed Dec 26, 2022
2 parents dd3848d + 434f639 commit 6ea1234
Show file tree
Hide file tree
Showing 18 changed files with 254 additions and 88 deletions.
5 changes: 3 additions & 2 deletions launcher/FileSystem.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
// SPDX-License-Identifier: GPL-3.0-only
/*
* PolyMC - Minecraft Launcher
* Prism Launcher - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
* Copyright (C) 2022 TheKodeToad <TheKodeToad@proton.me>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -226,7 +227,7 @@ bool deletePath(QString path)
return err.value() == 0;
}

bool trash(QString path, QString *pathInTrash = nullptr)
bool trash(QString path, QString *pathInTrash)
{
#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
return false;
Expand Down
5 changes: 3 additions & 2 deletions launcher/FileSystem.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
// SPDX-License-Identifier: GPL-3.0-only
/*
* PolyMC - Minecraft Launcher
* Prism Launcher - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
* Copyright (C) 2022 TheKodeToad <TheKodeToad@proton.me>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -129,7 +130,7 @@ bool deletePath(QString path);
/**
* Trash a folder / file
*/
bool trash(QString path, QString *pathInTrash);
bool trash(QString path, QString *pathInTrash = nullptr);

QString PathCombine(const QString& path1, const QString& path2);
QString PathCombine(const QString& path1, const QString& path2, const QString& path3);
Expand Down
7 changes: 6 additions & 1 deletion launcher/minecraft/World.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
// SPDX-License-Identifier: GPL-3.0-only
/*
* PolyMC - Minecraft Launcher
* Prism Launcher - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
* Copyright (C) 2022 TheKodeToad <TheKodeToad@proton.me>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -545,6 +546,10 @@ bool World::replace(World &with)
bool World::destroy()
{
if(!is_valid) return false;

if (FS::trash(m_containerFile.filePath()))
return true;

if (m_containerFile.isDir())
{
QDir d(m_containerFile.filePath());
Expand Down
4 changes: 4 additions & 0 deletions launcher/minecraft/mod/Resource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,5 +143,9 @@ bool Resource::enable(EnableAction action)
bool Resource::destroy()
{
m_type = ResourceType::UNKNOWN;

if (FS::trash(m_file_info.filePath()))
return true;

return FS::deletePath(m_file_info.filePath());
}
28 changes: 26 additions & 2 deletions launcher/ui/GuiUtil.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
// SPDX-License-Identifier: GPL-3.0-only
/*
* PolyMC - Minecraft Launcher
* Prism Launcher - Minecraft Launcher
* Copyright (C) 2022 Lenny McLennington <lenny@sneed.church>
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
* Copyright (C) 2022 TheKodeToad <TheKodeToad@proton.me>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -49,11 +50,34 @@
#include <DesktopServices.h>
#include <BuildConfig.h>

QString GuiUtil::uploadPaste(const QString &text, QWidget *parentWidget)
std::optional<QString> GuiUtil::uploadPaste(const QString &name, const QString &text, QWidget *parentWidget)
{
ProgressDialog dialog(parentWidget);
auto pasteTypeSetting = static_cast<PasteUpload::PasteType>(APPLICATION->settings()->get("PastebinType").toInt());
auto pasteCustomAPIBaseSetting = APPLICATION->settings()->get("PastebinCustomAPIBase").toString();

{
QUrl baseUrl;
if (pasteCustomAPIBaseSetting.isEmpty())
baseUrl = PasteUpload::PasteTypes[pasteTypeSetting].defaultBase;
else
baseUrl = pasteCustomAPIBaseSetting;

if (baseUrl.isValid())
{
auto response = CustomMessageBox::selectable(parentWidget, QObject::tr("Confirm Upload"),
QObject::tr("You are about to upload \"%1\" to %2.\n"
"You should double-check for personal information.\n\n"
"Are you sure?")
.arg(name, baseUrl.host()),
QMessageBox::Warning, QMessageBox::Yes | QMessageBox::No, QMessageBox::No)
->exec();

if (response != QMessageBox::Yes)
return {};
}
}

std::unique_ptr<PasteUpload> paste(new PasteUpload(parentWidget, text, pasteCustomAPIBaseSetting, pasteTypeSetting));

dialog.execWithTask(paste.get());
Expand Down
3 changes: 2 additions & 1 deletion launcher/ui/GuiUtil.h
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
#pragma once

#include <QWidget>
#include <optional>

namespace GuiUtil
{
QString uploadPaste(const QString &text, QWidget *parentWidget);
std::optional<QString> uploadPaste(const QString &name, const QString &text, QWidget *parentWidget);
void setClipboardText(const QString &text);
QStringList BrowseForFiles(QString context, QString caption, QString filter, QString defaultPath, QWidget *parentWidget);
QString BrowseForFile(QString context, QString caption, QString filter, QString defaultPath, QWidget *parentWidget);
Expand Down
39 changes: 21 additions & 18 deletions launcher/ui/MainWindow.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
// SPDX-License-Identifier: GPL-3.0-only
/*
* PolyMC - Minecraft Launcher
* Prism Launcher - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
* Copyright (C) 2022 TheKodeToad <TheKodeToad@proton.me>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -490,7 +491,7 @@ class MainWindow::Ui
if (!BuildConfig.BUG_TRACKER_URL.isEmpty()) {
helpMenu->addAction(actionReportBug);
}

if(!BuildConfig.MATRIX_URL.isEmpty()) {
helpMenu->addAction(actionMATRIX);
}
Expand Down Expand Up @@ -2093,21 +2094,23 @@ void MainWindow::on_actionDeleteInstance_triggered()

auto id = m_selectedInstance->id();

auto response =
CustomMessageBox::selectable(this, tr("CAREFUL!"),
tr("About to delete: %1\nThis may be permanent and will completely delete the instance.\n\nAre you sure?")
.arg(m_selectedInstance->name()),
QMessageBox::Warning, QMessageBox::Yes | QMessageBox::No, QMessageBox::No)
->exec();
auto response = CustomMessageBox::selectable(this, tr("Confirm Deletion"),
tr("You are about to delete \"%1\".\n"
"This may be permanent and will completely delete the instance.\n\n"
"Are you sure?")
.arg(m_selectedInstance->name()),
QMessageBox::Warning, QMessageBox::Yes | QMessageBox::No, QMessageBox::No)
->exec();

if (response == QMessageBox::Yes) {
if (APPLICATION->instances()->trashInstance(id)) {
ui->actionUndoTrashInstance->setEnabled(APPLICATION->instances()->trashedSomething());
return;
}
if (response != QMessageBox::Yes)
return;

APPLICATION->instances()->deleteInstance(id);
if (APPLICATION->instances()->trashInstance(id)) {
ui->actionUndoTrashInstance->setEnabled(APPLICATION->instances()->trashedSomething());
return;
}

APPLICATION->instances()->deleteInstance(id);
}

void MainWindow::on_actionExportInstance_triggered()
Expand Down Expand Up @@ -2252,7 +2255,7 @@ void MainWindow::on_actionCreateInstanceShortcut_triggered()
}

QString iconPath = FS::PathCombine(m_selectedInstance->instanceRoot(), "icon.png");

QFile iconFile(iconPath);
if (!iconFile.open(QFile::WriteOnly))
{
Expand All @@ -2261,7 +2264,7 @@ void MainWindow::on_actionCreateInstanceShortcut_triggered()
}
bool success = icon->icon().pixmap(64, 64).save(&iconFile, "PNG");
iconFile.close();

if (!success)
{
iconFile.remove();
Expand Down Expand Up @@ -2302,7 +2305,7 @@ void MainWindow::on_actionCreateInstanceShortcut_triggered()
}

QString iconPath = FS::PathCombine(m_selectedInstance->instanceRoot(), "icon.ico");

// part of fix for weird bug involving the window icon being replaced
// dunno why it happens, but this 2-line fix seems to be enough, so w/e
auto appIcon = APPLICATION->getThemedIcon("logo");
Expand All @@ -2325,7 +2328,7 @@ void MainWindow::on_actionCreateInstanceShortcut_triggered()
QMessageBox::critical(this, tr("Create instance shortcut"), tr("Failed to create icon for shortcut."));
return;
}

if (FS::createShortcut(FS::PathCombine(desktopPath, m_selectedInstance->name()),
QApplication::applicationFilePath(), { "--launch", m_selectedInstance->id() },
m_selectedInstance->name(), iconPath)) {
Expand Down
49 changes: 45 additions & 4 deletions launcher/ui/pages/instance/ExternalResourcesPage.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "ExternalResourcesPage.h"
#include "ui/dialogs/CustomMessageBox.h"
#include "ui_ExternalResourcesPage.h"

#include "DesktopServices.h"
Expand Down Expand Up @@ -128,7 +129,7 @@ bool ExternalResourcesPage::eventFilter(QObject* obj, QEvent* ev)
{
if (ev->type() != QEvent::KeyPress)
return QWidget::eventFilter(obj, ev);

QKeyEvent* keyEvent = static_cast<QKeyEvent*>(ev);
if (obj == ui->treeView)
return listFilter(keyEvent);
Expand All @@ -140,7 +141,6 @@ void ExternalResourcesPage::addItem()
{
if (!m_controlsEnabled)
return;


auto list = GuiUtil::BrowseForFiles(
helpPage(), tr("Select %1", "Select whatever type of files the page contains. Example: 'Loader Mods'").arg(displayName()),
Expand All @@ -157,8 +157,50 @@ void ExternalResourcesPage::removeItem()
{
if (!m_controlsEnabled)
return;

auto selection = m_filterModel->mapSelectionToSource(ui->treeView->selectionModel()->selection());

int count = 0;
bool folder = false;
for (auto& i : selection.indexes()) {
if (i.column() == 0) {
count++;

// if a folder is selected, show the confirmation dialog
if (m_model->at(i.row()).fileinfo().isDir())
folder = true;
}
}

QString text;
bool multiple = count > 1;

if (multiple) {
text = tr("You are about to remove %1 items.\n"
"This may be permanent and they will be gone from the folder.\n\n"
"Are you sure?")
.arg(count);
} else if (folder) {
text = tr("You are about to remove the folder \"%1\".\n"
"This may be permanent and it will be gone from the parent folder.\n\n"
"Are you sure?")
.arg(m_model->at(selection.indexes().at(0).row()).fileinfo().fileName());
}

if (!text.isEmpty()) {
auto response = CustomMessageBox::selectable(this, tr("Confirm Removal"), text, QMessageBox::Warning,
QMessageBox::Yes | QMessageBox::No, QMessageBox::No)
->exec();

if (response != QMessageBox::Yes)
return;
}

removeItems(selection);
}

void ExternalResourcesPage::removeItems(const QItemSelection& selection)
{
m_model->deleteResources(selection.indexes());
}

Expand Down Expand Up @@ -209,4 +251,3 @@ bool ExternalResourcesPage::onSelectionChanged(const QModelIndex& current, const

return true;
}

3 changes: 2 additions & 1 deletion launcher/ui/pages/instance/ExternalResourcesPage.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ class ExternalResourcesPage : public QMainWindow, public BasePage {
void filterTextChanged(const QString& newContents);

virtual void addItem();
virtual void removeItem();
void removeItem();
virtual void removeItems(const QItemSelection &selection);

virtual void enableItem();
virtual void disableItem();
Expand Down
29 changes: 12 additions & 17 deletions launcher/ui/pages/instance/LogPage.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
// SPDX-License-Identifier: GPL-3.0-only
/*
* PolyMC - Minecraft Launcher
* Prism Launcher - Minecraft Launcher
* Copyright (c) 2022 Jamie Mansfield <jmansfield@cadixdev.org>
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
* Copyright (C) 2022 TheKodeToad <TheKodeToad@proton.me>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -277,28 +278,22 @@ void LogPage::on_btnPaste_clicked()
//FIXME: turn this into a proper task and move the upload logic out of GuiUtil!
m_model->append(
MessageLevel::Launcher,
QString("%2: Log upload triggered at: %1").arg(
QDateTime::currentDateTime().toString(Qt::RFC2822Date),
BuildConfig.LAUNCHER_DISPLAYNAME
QString("Log upload triggered at: %1").arg(
QDateTime::currentDateTime().toString(Qt::RFC2822Date)
)
);
auto url = GuiUtil::uploadPaste(m_model->toPlainText(), this);
if(!url.isEmpty())
auto url = GuiUtil::uploadPaste(tr("Minecraft Log"), m_model->toPlainText(), this);
if(!url.has_value())
{
m_model->append(
MessageLevel::Launcher,
QString("%2: Log uploaded to: %1").arg(
url,
BuildConfig.LAUNCHER_DISPLAYNAME
)
);
m_model->append(MessageLevel::Error, QString("Log upload canceled"));
}
else if (url->isNull())
{
m_model->append(MessageLevel::Error, QString("Log upload failed!"));
}
else
{
m_model->append(
MessageLevel::Error,
QString("%1: Log upload failed!").arg(BuildConfig.LAUNCHER_DISPLAYNAME)
);
m_model->append(MessageLevel::Launcher, QString("Log uploaded to: %1").arg(url.value()));
}
}

Expand Down
10 changes: 3 additions & 7 deletions launcher/ui/pages/instance/ModFolderPage.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
// SPDX-License-Identifier: GPL-3.0-only
/*
* PolyMC - Minecraft Launcher
* Prism Launcher - Minecraft Launcher
* Copyright (c) 2022 Jamie Mansfield <jmansfield@cadixdev.org>
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
* Copyright (C) 2022 TheKodeToad <TheKodeToad@proton.me>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -139,13 +140,8 @@ bool ModFolderPage::onSelectionChanged(const QModelIndex& current, const QModelI
return true;
}

void ModFolderPage::removeItem()
void ModFolderPage::removeItems(const QItemSelection &selection)
{

if (!m_controlsEnabled)
return;

auto selection = m_filterModel->mapSelectionToSource(ui->treeView->selectionModel()->selection());
m_model->deleteMods(selection.indexes());
}

Expand Down

0 comments on commit 6ea1234

Please sign in to comment.