From 85b64ad76705cd152fb2b0525de75fe4e832c31c Mon Sep 17 00:00:00 2001
From: Petr Mrázek <peterix@gmail.com>
Date: Wed, 2 Nov 2016 02:33:55 +0100
Subject: NOISSUE MCEdit integration - remove old 'tool', replace with Worlds

---
 api/logic/tools/MCEditTool.cpp                 | 121 ++++++++-----------------
 api/logic/tools/MCEditTool.h                   |  29 ++----
 application/MainWindow.cpp                     |  29 +++---
 application/MainWindow.h                       |   2 +
 application/MultiMC.cpp                        |  12 +--
 application/MultiMC.h                          |  14 +--
 application/pages/WorldListPage.cpp            |  54 ++++-------
 application/pages/global/ExternalToolsPage.cpp |  23 ++---
 8 files changed, 100 insertions(+), 184 deletions(-)

diff --git a/api/logic/tools/MCEditTool.cpp b/api/logic/tools/MCEditTool.cpp
index 8e0d7ae2..74715d3f 100644
--- a/api/logic/tools/MCEditTool.cpp
+++ b/api/logic/tools/MCEditTool.cpp
@@ -8,117 +8,70 @@
 #include "BaseInstance.h"
 #include "minecraft/MinecraftInstance.h"
 
-MCEditTool::MCEditTool(SettingsObjectPtr settings, InstancePtr instance, QObject *parent)
-	: BaseDetachedTool(settings, instance, parent)
+MCEditTool::MCEditTool(SettingsObjectPtr settings)
 {
+	settings->registerSetting("MCEditPath");
+	m_settings = settings;
+}
+
+void MCEditTool::setPath(QString& path)
+{
+	m_settings->set("MCEditPath", path);
 }
 
-QString MCEditTool::getSave() const
+QString MCEditTool::path() const
 {
-	auto mcInstance = std::dynamic_pointer_cast<MinecraftInstance>(m_instance);
-	if(!mcInstance)
+	return m_settings->get("MCEditPath").toString();
+}
+
+bool MCEditTool::check(const QString& toolPath, QString& error)
+{
+	if (toolPath.isEmpty())
 	{
-		return QString();
+		error = QObject::tr("Path is empty");
+		return false;
 	}
-	QDir saves(mcInstance->minecraftRoot() + "/saves");
-	QStringList worlds = saves.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
-	QMutableListIterator<QString> it(worlds);
-	while (it.hasNext())
+	const QDir dir(toolPath);
+	if (!dir.exists())
 	{
-		it.next();
-		if (!QDir(saves.absoluteFilePath(it.value())).exists("level.dat"))
-		{
-			it.remove();
-		}
+		error = QObject::tr("Path does not exist");
+		return false;
 	}
-	bool ok = true;
-	// FIXME: mixing logic and UI!!!!
-	/*
-	const QString save = QInputDialog::getItem(QApplication::activeWindow(), tr("MCEdit"), tr("Choose which world to open:"),
-		worlds, 0, false, &ok);
-	if (ok)
+	if (!dir.exists("mcedit.sh") && !dir.exists("mcedit.py") && !dir.exists("mcedit.exe") && !dir.exists("Contents") && !dir.exists("mcedit2.exe"))
 	{
-		return saves.absoluteFilePath(save);
+		error = QObject::tr("Path does not seem to be a MCEdit path");
+		return false;
 	}
-	*/
-	return QString();
+	return true;
 }
 
-void MCEditTool::runImpl()
+QString MCEditTool::getProgramPath()
 {
-	const QString mceditPath = globalSettings->get("MCEditPath").toString();
-	const QString save = getSave();
-	if (save.isNull())
-	{
-		return;
-	}
 #ifdef Q_OS_OSX
-	QProcess *process = new QProcess();
-	connect(process, SIGNAL(finished(int, QProcess::ExitStatus)), process, SLOT(deleteLater()));
-	process->setProgram(mceditPath);
-	process->setArguments(QStringList() << save);
-	process->start();
+	return path();
 #else
+	const QString mceditPath = path();
 	QDir mceditDir(mceditPath);
-	QString program;
-	#ifdef Q_OS_LINUX
+#ifdef Q_OS_LINUX
 	if (mceditDir.exists("mcedit.sh"))
 	{
-		program = mceditDir.absoluteFilePath("mcedit.sh");
+		return mceditDir.absoluteFilePath("mcedit.sh");
 	}
 	else if (mceditDir.exists("mcedit.py"))
 	{
-		program = mceditDir.absoluteFilePath("mcedit.py");
+		return mceditDir.absoluteFilePath("mcedit.py");
 	}
-	#elif defined(Q_OS_WIN32)
+	return QString();
+#elif defined(Q_OS_WIN32)
 	if (mceditDir.exists("mcedit.exe"))
 	{
-		program = mceditDir.absoluteFilePath("mcedit.exe");
+		return mceditDir.absoluteFilePath("mcedit.exe");
 	}
 	else if (mceditDir.exists("mcedit2.exe"))
 	{
-		program = mceditDir.absoluteFilePath("mcedit2.exe");
+		return mceditDir.absoluteFilePath("mcedit2.exe");
 	}
-	#endif
-	/*
-	if(program.size())
-	{
-		DesktopServices::openFile(program, save, mceditPath);
-	}
-	*/
+	return QString();
+#endif
 #endif
-}
-
-void MCEditFactory::registerSettings(SettingsObjectPtr settings)
-{
-	settings->registerSetting("MCEditPath");
-	globalSettings = settings;
-}
-BaseExternalTool *MCEditFactory::createTool(InstancePtr instance, QObject *parent)
-{
-	return new MCEditTool(globalSettings, instance, parent);
-}
-bool MCEditFactory::check(QString *error)
-{
-	return check(globalSettings->get("MCEditPath").toString(), error);
-}
-bool MCEditFactory::check(const QString &path, QString *error)
-{
-	if (path.isEmpty())
-	{
-		*error = QObject::tr("Path is empty");
-		return false;
-	}
-	const QDir dir(path);
-	if (!dir.exists())
-	{
-		*error = QObject::tr("Path does not exist");
-		return false;
-	}
-	if (!dir.exists("mcedit.sh") && !dir.exists("mcedit.py") && !dir.exists("mcedit.exe") && !dir.exists("Contents") && !dir.exists("mcedit2.exe"))
-	{
-		*error = QObject::tr("Path does not seem to be a MCEdit path");
-		return false;
-	}
-	return true;
 }
diff --git a/api/logic/tools/MCEditTool.h b/api/logic/tools/MCEditTool.h
index c287f1ea..51feb1fe 100644
--- a/api/logic/tools/MCEditTool.h
+++ b/api/logic/tools/MCEditTool.h
@@ -1,26 +1,17 @@
 #pragma once
 
-#include "BaseExternalTool.h"
-
+#include <QString>
+#include "settings/SettingsObject.h"
 #include "multimc_logic_export.h"
 
-class MULTIMC_LOGIC_EXPORT MCEditTool : public BaseDetachedTool
-{
-	Q_OBJECT
-public:
-	explicit MCEditTool(SettingsObjectPtr settings, InstancePtr instance, QObject *parent = 0);
-
-protected:
-	QString getSave() const;
-	void runImpl() override;
-};
-
-class MULTIMC_LOGIC_EXPORT MCEditFactory : public BaseDetachedToolFactory
+class MULTIMC_LOGIC_EXPORT MCEditTool
 {
 public:
-	QString name() const override { return "MCEdit"; }
-	void registerSettings(SettingsObjectPtr settings) override;
-	BaseExternalTool *createTool(InstancePtr instance, QObject *parent = 0) override;
-	bool check(QString *error) override;
-	bool check(const QString &path, QString *error) override;
+	MCEditTool(SettingsObjectPtr settings);
+	void setPath(QString & path);
+	QString path() const;
+	bool check(const QString &toolPath, QString &error);
+	QString getProgramPath();
+private:
+	SettingsObjectPtr m_settings;
 };
diff --git a/application/MainWindow.cpp b/application/MainWindow.cpp
index 6d88a14e..bf9da0dc 100644
--- a/application/MainWindow.cpp
+++ b/application/MainWindow.cpp
@@ -110,6 +110,7 @@ public:
 	QAction *actionChangeInstIcon;
 	QAction *actionEditInstNotes;
 	QAction *actionEditInstance;
+	QAction *actionWorlds;
 	QAction *actionViewSelectedInstFolder;
 	QAction *actionDeleteInstance;
 	QAction *actionConfig_Folder;
@@ -187,6 +188,8 @@ public:
 		actionEditInstNotes->setObjectName(QStringLiteral("actionEditInstNotes"));
 		actionEditInstance = new QAction(MainWindow);
 		actionEditInstance->setObjectName(QStringLiteral("actionEditInstance"));
+		actionWorlds = new QAction(MainWindow);
+		actionWorlds->setObjectName(QStringLiteral("actionWorlds"));
 		actionViewSelectedInstFolder = new QAction(MainWindow);
 		actionViewSelectedInstFolder->setObjectName(QStringLiteral("actionViewSelectedInstFolder"));
 		actionDeleteInstance = new QAction(MainWindow);
@@ -280,6 +283,7 @@ public:
 		instanceToolBar->addAction(actionEditInstance);
 		instanceToolBar->addAction(actionInstanceSettings);
 		instanceToolBar->addAction(actionEditInstNotes);
+		instanceToolBar->addAction(actionWorlds);
 		instanceToolBar->addAction(actionScreenshots);
 		instanceToolBar->addSeparator();
 		instanceToolBar->addAction(actionViewSelectedInstFolder);
@@ -330,6 +334,8 @@ public:
 		actionChangeInstIcon->setToolTip(tr("Change the selected instance's icon."));
 		actionEditInstNotes->setText(tr("Edit Notes"));
 		actionEditInstNotes->setToolTip(tr("Edit the notes for the selected instance."));
+		actionWorlds->setText(tr("View Worlds"));
+		actionWorlds->setToolTip(tr("View the worlds of this instance."));
 		actionEditInstance->setText(tr("Edit Instance"));
 		actionEditInstance->setToolTip(tr("Change the instance settings, mods and versions."));
 		actionViewSelectedInstFolder->setText(tr("Instance Folder"));
@@ -690,24 +696,6 @@ void MainWindow::updateToolsMenu()
 					});
 		}
 	}
-	launchMenu->addSeparator()->setText(tr("Tools"));
-	for (auto tool : MMC->tools().values())
-	{
-		QAction *toolAction = launchMenu->addAction(tool->name());
-		QString error;
-		if (!tool->check(&error))
-		{
-			toolAction->setDisabled(true);
-			toolAction->setToolTip(tr("Tool not setup correctly. Go into settings, \"External Tools\"."));
-		}
-		else
-		{
-			connect(toolAction, &QAction::triggered, [this, tool]()
-					{
-						tool->createDetachedTool(m_selectedInstance, this)->run();
-					});
-		}
-	}
 	ui->actionLaunchInstance->setMenu(launchMenu);
 }
 
@@ -1250,6 +1238,11 @@ void MainWindow::on_actionEditInstNotes_triggered()
 	MMC->showInstanceWindow(m_selectedInstance, "notes");
 }
 
+void MainWindow::on_actionWorlds_triggered()
+{
+	MMC->showInstanceWindow(m_selectedInstance, "worlds");
+}
+
 void MainWindow::on_actionEditInstance_triggered()
 {
 	MMC->showInstanceWindow(m_selectedInstance);
diff --git a/application/MainWindow.h b/application/MainWindow.h
index e499f162..506f7ee3 100644
--- a/application/MainWindow.h
+++ b/application/MainWindow.h
@@ -115,6 +115,8 @@ private slots:
 
 	void on_actionEditInstNotes_triggered();
 
+	void on_actionWorlds_triggered();
+
 	void on_actionScreenshots_triggered();
 
 	void taskEnd();
diff --git a/application/MultiMC.cpp b/application/MultiMC.cpp
index 6c284b35..b3615580 100644
--- a/application/MultiMC.cpp
+++ b/application/MultiMC.cpp
@@ -271,12 +271,7 @@ MultiMC::MultiMC(int &argc, char **argv) : QApplication(argc, argv)
 		profiler->registerSettings(m_settings);
 	}
 
-	//FIXME: what to do with these?
-	m_tools.insert("mcedit", std::shared_ptr<BaseDetachedToolFactory>(new MCEditFactory()));
-	for (auto tool : m_tools.values())
-	{
-		tool->registerSettings(m_settings);
-	}
+	initMCEdit();
 
 	connect(this, SIGNAL(aboutToQuit()), SLOT(onExit()));
 
@@ -628,6 +623,11 @@ void MultiMC::initGlobalSettings()
 	}
 }
 
+void MultiMC::initMCEdit()
+{
+	m_mcedit.reset(new MCEditTool(m_settings));
+}
+
 std::shared_ptr<LWJGLVersionList> MultiMC::lwjgllist()
 {
 	if (!m_lwjgllist)
diff --git a/application/MultiMC.h b/application/MultiMC.h
index e7f41f18..4deb95d1 100644
--- a/application/MultiMC.h
+++ b/application/MultiMC.h
@@ -33,6 +33,7 @@ class BaseProfilerFactory;
 class BaseDetachedToolFactory;
 class TranslationDownloader;
 class ITheme;
+class MCEditTool;
 
 #if defined(MMC)
 #undef MMC
@@ -105,6 +106,11 @@ public:
 		return m_icons;
 	}
 
+	MCEditTool *mcedit() const
+	{
+		return m_mcedit.get();
+	}
+
 	std::shared_ptr<MojangAccountList> accounts() const
 	{
 		return m_accounts;
@@ -120,11 +126,6 @@ public:
 		return m_profilers;
 	}
 
-	const QMap<QString, std::shared_ptr<BaseDetachedToolFactory>> &tools() const
-	{
-		return m_tools;
-	}
-
 	/// this is the root of the 'installation'. Used for automatic updates
 	const QString &root()
 	{
@@ -166,6 +167,7 @@ private:
 	void initNetwork();
 	void initInstances();
 	void initAccounts();
+	void initMCEdit();
 
 private:
 	QDateTime startTime;
@@ -186,9 +188,9 @@ private:
 	std::shared_ptr<TranslationDownloader> m_translationChecker;
 	std::shared_ptr<GenericPageProvider> m_globalSettingsProvider;
 	std::map<QString, std::unique_ptr<ITheme>> m_themes;
+	std::unique_ptr<MCEditTool> m_mcedit;
 
 	QMap<QString, std::shared_ptr<BaseProfilerFactory>> m_profilers;
-	QMap<QString, std::shared_ptr<BaseDetachedToolFactory>> m_tools;
 
 	QString m_rootPath;
 	Status m_status = MultiMC::Failed;
diff --git a/application/pages/WorldListPage.cpp b/application/pages/WorldListPage.cpp
index fcef716b..a4f17744 100644
--- a/application/pages/WorldListPage.cpp
+++ b/application/pages/WorldListPage.cpp
@@ -24,10 +24,11 @@
 #include <QMessageBox>
 #include <QTreeView>
 #include <QInputDialog>
-
+#include <tools/MCEditTool.h>
 
 #include "MultiMC.h"
 #include <GuiUtil.h>
+#include <QProcess>
 
 WorldListPage::WorldListPage(BaseInstance *inst, std::shared_ptr<WorldList> worlds, QString id,
 							 QString iconName, QString displayName, QString helpPage,
@@ -148,7 +149,8 @@ void WorldListPage::on_copySeedBtn_clicked()
 
 void WorldListPage::on_mcEditBtn_clicked()
 {
-	const QString mceditPath = MMC->settings()->get("MCEditPath").toString();
+	auto mcedit = MMC->mcedit();
+	const QString mceditPath = mcedit->path();
 
 	QModelIndex index = getSelectedWorld();
 
@@ -162,49 +164,27 @@ void WorldListPage::on_mcEditBtn_clicked()
 
 	auto fullPath = m_worlds->data(index, WorldList::FolderRole).toString();
 
-#ifdef Q_OS_OSX
-	QProcess *process = new QProcess();
-	connect(process, SIGNAL(finished(int, QProcess::ExitStatus)), process, SLOT(deleteLater()));
-	process->setProgram(mceditPath);
-	process->setArguments(QStringList() << fullPath);
-	process->start();
-#else
-	QDir mceditDir(mceditPath);
-	QString program;
-	#ifdef Q_OS_LINUX
-	if (mceditDir.exists("mcedit.sh"))
-	{
-		program = mceditDir.absoluteFilePath("mcedit.sh");
-	}
-	else if (mceditDir.exists("mcedit.py"))
-	{
-		program = mceditDir.absoluteFilePath("mcedit.py");
-	}
-	#elif defined(Q_OS_WIN32)
-	if (mceditDir.exists("mcedit.exe"))
-	{
-		program = mceditDir.absoluteFilePath("mcedit.exe");
-	}
-	else if (mceditDir.exists("mcedit2.exe"))
-	{
-		program = mceditDir.absoluteFilePath("mcedit2.exe");
-	}
-	#endif
+	auto program = mcedit->getProgramPath();
 	if(program.size())
 	{
-		qint64 pid = 0;
-
-		DesktopServices::openFile(program, fullPath, mceditPath, &pid);
-		if(pid == 0)
+		qint64 pid;
+		if(!QProcess::startDetached(program, QStringList() << fullPath, mceditPath, &pid))
 		{
-			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.")
+			);
 		}
 	}
 	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."));
+		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.")
+		);
 	}
-#endif
 }
 
 void WorldListPage::worldChanged(const QModelIndex &current, const QModelIndex &previous)
diff --git a/application/pages/global/ExternalToolsPage.cpp b/application/pages/global/ExternalToolsPage.cpp
index e8091dee..4c3375c8 100644
--- a/application/pages/global/ExternalToolsPage.cpp
+++ b/application/pages/global/ExternalToolsPage.cpp
@@ -24,6 +24,7 @@
 #include "tools/BaseProfiler.h"
 #include <FileSystem.h>
 #include "MultiMC.h"
+#include <tools/MCEditTool.h>
 
 ExternalToolsPage::ExternalToolsPage(QWidget *parent) :
 	QWidget(parent),
@@ -93,8 +94,7 @@ void ExternalToolsPage::on_jprofilerPathBtn_clicked()
 		QString cooked_dir = FS::NormalizePath(raw_dir);
 		if (!MMC->profilers()["jprofiler"]->check(cooked_dir, &error))
 		{
-			QMessageBox::critical(this, tr("Error"),
-								  tr("Error while checking JProfiler install:\n%1").arg(error));
+			QMessageBox::critical(this, tr("Error"), tr("Error while checking JProfiler install:\n%1").arg(error));
 			continue;
 		}
 		else
@@ -109,8 +109,7 @@ void ExternalToolsPage::on_jprofilerCheckBtn_clicked()
 	QString error;
 	if (!MMC->profilers()["jprofiler"]->check(ui->jprofilerPathEdit->text(), &error))
 	{
-		QMessageBox::critical(this, tr("Error"),
-							  tr("Error while checking JProfiler install:\n%1").arg(error));
+		QMessageBox::critical(this, tr("Error"), tr("Error while checking JProfiler install:\n%1").arg(error));
 	}
 	else
 	{
@@ -132,8 +131,7 @@ void ExternalToolsPage::on_jvisualvmPathBtn_clicked()
 		QString cooked_dir = FS::NormalizePath(raw_dir);
 		if (!MMC->profilers()["jvisualvm"]->check(cooked_dir, &error))
 		{
-			QMessageBox::critical(this, tr("Error"),
-								  tr("Error while checking JVisualVM install:\n%1").arg(error));
+			QMessageBox::critical(this, tr("Error"), tr("Error while checking JVisualVM install:\n%1").arg(error));
 			continue;
 		}
 		else
@@ -148,8 +146,7 @@ void ExternalToolsPage::on_jvisualvmCheckBtn_clicked()
 	QString error;
 	if (!MMC->profilers()["jvisualvm"]->check(ui->jvisualvmPathEdit->text(), &error))
 	{
-		QMessageBox::critical(this, tr("Error"),
-							  tr("Error while checking JVisualVM install:\n%1").arg(error));
+		QMessageBox::critical(this, tr("Error"), tr("Error while checking JVisualVM install:\n%1").arg(error));
 	}
 	else
 	{
@@ -174,10 +171,9 @@ void ExternalToolsPage::on_mceditPathBtn_clicked()
 			break;
 		}
 		QString cooked_dir = FS::NormalizePath(raw_dir);
-		if (!MMC->tools()["mcedit"]->check(cooked_dir, &error))
+		if (!MMC->mcedit()->check(cooked_dir, error))
 		{
-			QMessageBox::critical(this, tr("Error"),
-								  tr("Error while checking MCEdit install:\n%1").arg(error));
+			QMessageBox::critical(this, tr("Error"), tr("Error while checking MCEdit install:\n%1").arg(error));
 			continue;
 		}
 		else
@@ -190,10 +186,9 @@ void ExternalToolsPage::on_mceditPathBtn_clicked()
 void ExternalToolsPage::on_mceditCheckBtn_clicked()
 {
 	QString error;
-	if (!MMC->tools()["mcedit"]->check(ui->mceditPathEdit->text(), &error))
+	if (!!MMC->mcedit()->check(ui->mceditPathEdit->text(), error))
 	{
-		QMessageBox::critical(this, tr("Error"),
-							  tr("Error while checking MCEdit install:\n%1").arg(error));
+		QMessageBox::critical(this, tr("Error"), tr("Error while checking MCEdit install:\n%1").arg(error));
 	}
 	else
 	{
-- 
cgit