Merge branch 'develop'
This commit is contained in:
		| @@ -217,6 +217,8 @@ gui/EditNotesDialog.h | ||||
| gui/EditNotesDialog.cpp | ||||
| gui/MCModInfoFrame.h | ||||
| gui/MCModInfoFrame.cpp | ||||
| gui/CustomMessageBox.h | ||||
| gui/CustomMessageBox.cpp | ||||
|  | ||||
| # Base classes and infrastructure | ||||
| logic/BaseVersion.h | ||||
|   | ||||
							
								
								
									
										28
									
								
								MultiMC.cpp
									
									
									
									
									
								
							
							
						
						
									
										28
									
								
								MultiMC.cpp
									
									
									
									
									
								
							| @@ -32,8 +32,8 @@ using namespace Util::Commandline; | ||||
|  | ||||
| MultiMC::MultiMC(int &argc, char **argv) : QApplication(argc, argv) | ||||
| { | ||||
|     setOrganizationName("MultiMC"); | ||||
|     setApplicationName("MultiMC5"); | ||||
| 	setOrganizationName("MultiMC"); | ||||
| 	setApplicationName("MultiMC5"); | ||||
|  | ||||
| 	initTranslations(); | ||||
|  | ||||
| @@ -139,13 +139,19 @@ MultiMC::MultiMC(int &argc, char **argv) : QApplication(argc, argv) | ||||
| 	initGlobalSettings(); | ||||
|  | ||||
| 	// and instances | ||||
| 	m_instances.reset(new InstanceList(m_settings->get("InstanceDir").toString(), this)); | ||||
| 	auto InstDirSetting = m_settings->getSetting("InstanceDir"); | ||||
| 	m_instances.reset(new InstanceList(InstDirSetting->get().toString(), this)); | ||||
| 	QLOG_INFO() << "Loading Instances..."; | ||||
| 	m_instances->loadList(); | ||||
| 	connect(InstDirSetting, SIGNAL(settingChanged(const Setting &, QVariant)), | ||||
| 			m_instances.get(), SLOT(on_InstFolderChanged(const Setting &, QVariant))); | ||||
|  | ||||
| 	// init the http meta cache | ||||
| 	initHttpMetaCache(); | ||||
|  | ||||
| 	// set up a basic autodetected proxy (system default) | ||||
| 	QNetworkProxyFactory::setUseSystemConfiguration(true); | ||||
|  | ||||
| 	// create the global network manager | ||||
| 	m_qnam.reset(new QNetworkAccessManager(this)); | ||||
|  | ||||
| @@ -348,20 +354,24 @@ std::shared_ptr<JavaVersionList> MultiMC::javalist() | ||||
| 	return m_javalist; | ||||
| } | ||||
|  | ||||
| int main_gui(MultiMC & app) | ||||
| { | ||||
| 	// show main window | ||||
| 	MainWindow mainWin; | ||||
| 	mainWin.show(); | ||||
| 	mainWin.checkSetDefaultJava(); | ||||
| 	return app.exec(); | ||||
| } | ||||
|  | ||||
| int main(int argc, char *argv[]) | ||||
| { | ||||
| 	// initialize Qt | ||||
| 	MultiMC app(argc, argv); | ||||
|  | ||||
| 	// show main window | ||||
| 	MainWindow mainWin; | ||||
| 	mainWin.show(); | ||||
| 	mainWin.checkSetDefaultJava(); | ||||
|  | ||||
| 	switch (app.status()) | ||||
| 	{ | ||||
| 	case MultiMC::Initialized: | ||||
| 		return app.exec(); | ||||
| 		return main_gui(app); | ||||
| 	case MultiMC::Failed: | ||||
| 		return 1; | ||||
| 	case MultiMC::Succeeded: | ||||
|   | ||||
| @@ -19,6 +19,7 @@ | ||||
| #define CMDUTILS_H | ||||
|  | ||||
| #include <exception> | ||||
| #include <stdexcept> | ||||
|  | ||||
| #include <QString> | ||||
| #include <QVariant> | ||||
| @@ -83,16 +84,10 @@ enum Enum | ||||
| /** | ||||
|  * @brief The ParsingError class | ||||
|  */ | ||||
| class LIBUTIL_EXPORT ParsingError : public std::exception | ||||
| class LIBUTIL_EXPORT ParsingError : public std::runtime_error | ||||
| { | ||||
| public: | ||||
| 	ParsingError(const QString &what); | ||||
| 	ParsingError(const ParsingError &e); | ||||
| 	~ParsingError() throw() {} | ||||
| 	const char *what() const throw(); | ||||
| 	QString qwhat() const; | ||||
| private: | ||||
| 	QString m_what; | ||||
| }; | ||||
|  | ||||
| /** | ||||
|   | ||||
| @@ -25,6 +25,16 @@ LIBUTIL_EXPORT QString PathCombine(QString path1, QString path2, QString path3); | ||||
|  | ||||
| LIBUTIL_EXPORT QString AbsolutePath(QString path); | ||||
|  | ||||
| /** | ||||
|  * Normalize path | ||||
|  *  | ||||
|  * Any paths inside the current directory will be normalized to relative paths (to current) | ||||
|  * Other paths will be made absolute | ||||
|  *  | ||||
|  * Returns false if the path logic somehow filed (and normalizedPath in invalid) | ||||
|  */ | ||||
| QString NormalizePath(QString path); | ||||
|  | ||||
| LIBUTIL_EXPORT QString RemoveInvalidFilenameChars(QString string, QChar replaceWith = '-'); | ||||
|  | ||||
| LIBUTIL_EXPORT QString DirNameFromString(QString string, QString inDir = "."); | ||||
|   | ||||
| @@ -463,21 +463,8 @@ void Parser::getPrefix(QString &opt, QString &flag) | ||||
|  | ||||
| // ParsingError | ||||
| ParsingError::ParsingError(const QString &what) | ||||
| :std::runtime_error(what.toStdString()) | ||||
| { | ||||
| 	m_what = what; | ||||
| } | ||||
| ParsingError::ParsingError(const ParsingError &e) | ||||
| { | ||||
| 	m_what = e.m_what; | ||||
| } | ||||
|  | ||||
| const char *ParsingError::what() const throw() | ||||
| { | ||||
| 	return m_what.toLocal8Bit().constData(); | ||||
| } | ||||
| QString ParsingError::qwhat() const | ||||
| { | ||||
| 	return m_what; | ||||
| } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -39,6 +39,30 @@ QString AbsolutePath(QString path) | ||||
| 	return QFileInfo(path).absolutePath(); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Normalize path | ||||
|  *  | ||||
|  * Any paths inside the current directory will be normalized to relative paths (to current) | ||||
|  * Other paths will be made absolute | ||||
|  */ | ||||
| QString NormalizePath(QString path) | ||||
| { | ||||
| 	QDir a = QDir::currentPath(); | ||||
| 	QString currentAbsolute = a.absolutePath(); | ||||
|  | ||||
| 	QDir b(path); | ||||
| 	QString newAbsolute = b.absolutePath(); | ||||
|  | ||||
| 	if (newAbsolute.startsWith(currentAbsolute)) | ||||
| 	{ | ||||
| 		return a.relativeFilePath(newAbsolute); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		return newAbsolute; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| QString badFilenameChars = "\"\\/?<>:*|!"; | ||||
|  | ||||
| QString RemoveInvalidFilenameChars(QString string, QChar replaceWith) | ||||
|   | ||||
							
								
								
									
										19
									
								
								gui/CustomMessageBox.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								gui/CustomMessageBox.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | ||||
| #include "CustomMessageBox.h" | ||||
|  | ||||
| namespace CustomMessageBox | ||||
| { | ||||
| 	QMessageBox *selectable(QWidget *parent, const QString &title, const QString &text, | ||||
| 							QMessageBox::Icon icon,	QMessageBox::StandardButtons buttons, | ||||
| 							QMessageBox::StandardButton defaultButton) | ||||
| 	{ | ||||
| 		QMessageBox *messageBox = new QMessageBox(parent); | ||||
| 		messageBox->setWindowTitle(title); | ||||
| 		messageBox->setText(text); | ||||
| 		messageBox->setStandardButtons(buttons); | ||||
| 		messageBox->setDefaultButton(defaultButton); | ||||
| 		messageBox->setTextInteractionFlags(Qt::TextSelectableByMouse); | ||||
| 		messageBox->setIcon(icon); | ||||
|  | ||||
| 		return messageBox; | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										11
									
								
								gui/CustomMessageBox.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								gui/CustomMessageBox.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include <QMessageBox> | ||||
|  | ||||
| namespace CustomMessageBox | ||||
| { | ||||
| 	QMessageBox *selectable(QWidget *parent, const QString &title, const QString &text, | ||||
| 							QMessageBox::Icon icon = QMessageBox::NoIcon, | ||||
| 							QMessageBox::StandardButtons buttons = QMessageBox::Ok, | ||||
| 							QMessageBox::StandardButton defaultButton = QMessageBox::NoButton); | ||||
| } | ||||
| @@ -69,4 +69,4 @@ void LabeledToolButton::resizeEvent(QResizeEvent * event) | ||||
| { | ||||
| 	m_label->setGeometry(QRect(4, 4, width()-8, height()-8)); | ||||
| 	QWidget::resizeEvent(event); | ||||
| } | ||||
| } | ||||
|   | ||||
| @@ -15,6 +15,7 @@ | ||||
|  | ||||
| #include "MCModInfoFrame.h" | ||||
| #include "ui_MCModInfoFrame.h" | ||||
| #include "CustomMessageBox.h" | ||||
| #include <QMessageBox> | ||||
| #include <QtGui> | ||||
| void MCModInfoFrame::updateWithMod(Mod &m) | ||||
| @@ -104,7 +105,5 @@ void MCModInfoFrame::setModDescription(QString text) | ||||
| } | ||||
| void MCModInfoFrame::modDescEllipsisHandler(const QString &link) | ||||
| { | ||||
| 	QMessageBox msgbox; | ||||
| 	msgbox.setText(desc); | ||||
| 	msgbox.exec(); | ||||
| 	CustomMessageBox::selectable(this, tr(""), desc)->show(); | ||||
| } | ||||
|   | ||||
| @@ -1,4 +1,5 @@ | ||||
| #include "ModEditDialogCommon.h" | ||||
| #include "CustomMessageBox.h" | ||||
| #include <QDesktopServices> | ||||
| #include <QMessageBox> | ||||
| #include <QString> | ||||
| @@ -33,8 +34,8 @@ void showWebsiteForMod(QWidget *parentDlg, Mod &m) | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		QMessageBox::warning( | ||||
| 			parentDlg, parentDlg->tr("How sad!"), | ||||
| 			parentDlg->tr("The mod author didn't provide a website link for this mod.")); | ||||
| 		CustomMessageBox::selectable(parentDlg, parentDlg->tr("How sad!"), | ||||
| 									 parentDlg->tr("The mod author didn't provide a website link for this mod."), | ||||
| 									 QMessageBox::Warning); | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -23,6 +23,7 @@ | ||||
| #include "logic/ForgeInstaller.h" | ||||
| #include "gui/versionselectdialog.h" | ||||
| #include "gui/platform.h" | ||||
| #include "gui/CustomMessageBox.h" | ||||
| #include "ProgressDialog.h" | ||||
|  | ||||
| #include <pathutils.h> | ||||
| @@ -110,11 +111,11 @@ void OneSixModEditDialog::on_customizeBtn_clicked() | ||||
|  | ||||
| void OneSixModEditDialog::on_revertBtn_clicked() | ||||
| { | ||||
| 	auto reply = QMessageBox::question( | ||||
| 		this, tr("Revert?"), tr("Do you want to revert the " | ||||
| 								"version of this instance to its original configuration?"), | ||||
| 		QMessageBox::Yes | QMessageBox::No); | ||||
| 	if (reply == QMessageBox::Yes) | ||||
| 	auto response = CustomMessageBox::selectable(this, tr("Revert?"), | ||||
| 												tr("Do you want to revert the " | ||||
| 												"version of this instance to its original configuration?"), | ||||
| 												QMessageBox::Question, QMessageBox::Yes | QMessageBox::No)->exec(); | ||||
| 	if (response == QMessageBox::Yes) | ||||
| 	{ | ||||
| 		if (m_inst->revertCustomVersion()) | ||||
| 		{ | ||||
|   | ||||
| @@ -5,6 +5,7 @@ | ||||
| #include <QMessageBox> | ||||
|  | ||||
| #include <gui/platform.h> | ||||
| #include <gui/CustomMessageBox.h> | ||||
|  | ||||
| ConsoleWindow::ConsoleWindow(MinecraftProcess *mcproc, QWidget *parent) : | ||||
| 	QDialog(parent), | ||||
| @@ -12,8 +13,9 @@ ConsoleWindow::ConsoleWindow(MinecraftProcess *mcproc, QWidget *parent) : | ||||
| 	m_mayclose(true), | ||||
| 	proc(mcproc) | ||||
| { | ||||
|     MultiMCPlatform::fixWM_CLASS(this); | ||||
| 	MultiMCPlatform::fixWM_CLASS(this); | ||||
| 	ui->setupUi(this); | ||||
| 	this->setWindowFlags(Qt::Window); | ||||
| 	connect(mcproc, SIGNAL(ended(BaseInstance*)), this, SLOT(onEnded(BaseInstance*))); | ||||
| } | ||||
|  | ||||
| @@ -96,17 +98,13 @@ void ConsoleWindow::closeEvent(QCloseEvent * event) | ||||
| void ConsoleWindow::on_btnKillMinecraft_clicked() | ||||
| { | ||||
| 	ui->btnKillMinecraft->setEnabled(false); | ||||
| 	QMessageBox r_u_sure; | ||||
| 	//: Main question of the kill confirmation dialog | ||||
| 	r_u_sure.setText(tr("Kill Minecraft?")); | ||||
| 	r_u_sure.setInformativeText(tr("This can cause the instance to get corrupted and should only be used if Minecraft is frozen for some reason")); | ||||
| 	r_u_sure.setStandardButtons(QMessageBox::Yes | QMessageBox::No); | ||||
| 	r_u_sure.setDefaultButton(QMessageBox::Yes); | ||||
| 	if (r_u_sure.exec() == QMessageBox::Yes) | ||||
| 	auto response = CustomMessageBox::selectable(this, tr("Kill Minecraft?"), | ||||
| 												 tr("This can cause the instance to get corrupted and should only be used if Minecraft is frozen for some reason"), | ||||
| 												 QMessageBox::Question, QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes)->exec(); | ||||
| 	if (response == QMessageBox::Yes) | ||||
| 		proc->killMinecraft(); | ||||
| 	else | ||||
| 		ui->btnKillMinecraft->setEnabled(true); | ||||
| 	r_u_sure.close(); | ||||
| } | ||||
|  | ||||
| void ConsoleWindow::onEnded(BaseInstance *instance) | ||||
|   | ||||
| @@ -19,6 +19,9 @@ | ||||
|      <property name="text"> | ||||
|       <string><span style=" color:#ff0000;">Error</span></string> | ||||
|      </property> | ||||
|      <property name="textInteractionFlags"> | ||||
|       <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set> | ||||
|      </property> | ||||
|     </widget> | ||||
|    </item> | ||||
|    <item> | ||||
| @@ -85,19 +88,6 @@ | ||||
|        </property> | ||||
|       </widget> | ||||
|      </item> | ||||
|      <item row="0" column="5" rowspan="2"> | ||||
|       <widget class="QPushButton" name="forgetButton"> | ||||
|        <property name="sizePolicy"> | ||||
|         <sizepolicy hsizetype="Minimum" vsizetype="Minimum"> | ||||
|          <horstretch>0</horstretch> | ||||
|          <verstretch>0</verstretch> | ||||
|         </sizepolicy> | ||||
|        </property> | ||||
|        <property name="text"> | ||||
|         <string>Forget</string> | ||||
|        </property> | ||||
|       </widget> | ||||
|      </item> | ||||
|     </layout> | ||||
|    </item> | ||||
|    <item> | ||||
| @@ -128,6 +118,19 @@ | ||||
|        </property> | ||||
|       </widget> | ||||
|      </item> | ||||
|      <item> | ||||
|       <widget class="QPushButton" name="forgetButton"> | ||||
|        <property name="sizePolicy"> | ||||
|         <sizepolicy hsizetype="Minimum" vsizetype="Minimum"> | ||||
|          <horstretch>0</horstretch> | ||||
|          <verstretch>0</verstretch> | ||||
|         </sizepolicy> | ||||
|        </property> | ||||
|        <property name="text"> | ||||
|         <string>Forget</string> | ||||
|        </property> | ||||
|       </widget> | ||||
|      </item> | ||||
|     </layout> | ||||
|    </item> | ||||
|    <item> | ||||
|   | ||||
| @@ -50,6 +50,7 @@ | ||||
| #include "gui/consolewindow.h" | ||||
| #include "gui/instancesettings.h" | ||||
| #include "gui/platform.h" | ||||
| #include "gui/CustomMessageBox.h" | ||||
|  | ||||
| #include "logic/lists/InstanceList.h" | ||||
| #include "logic/lists/MinecraftVersionList.h" | ||||
| @@ -281,20 +282,26 @@ void MainWindow::on_actionAddInstance_triggered() | ||||
| 		return; | ||||
|  | ||||
| 	case InstanceFactory::InstExists: | ||||
| 	{ | ||||
| 		errorMsg += "An instance with the given directory name already exists."; | ||||
| 		QMessageBox::warning(this, "Error", errorMsg); | ||||
| 		CustomMessageBox::selectable(this, tr("Error"), errorMsg, QMessageBox::Warning)->show(); | ||||
| 		break; | ||||
| 	} | ||||
|  | ||||
| 	case InstanceFactory::CantCreateDir: | ||||
| 	{ | ||||
| 		errorMsg += "Failed to create the instance directory."; | ||||
| 		QMessageBox::warning(this, "Error", errorMsg); | ||||
| 		CustomMessageBox::selectable(this, tr("Error"), errorMsg, QMessageBox::Warning)->show(); | ||||
| 		break; | ||||
| 	} | ||||
|  | ||||
| 	default: | ||||
| 	{ | ||||
| 		errorMsg += QString("Unknown instance loader error %1").arg(error); | ||||
| 		QMessageBox::warning(this, "Error", errorMsg); | ||||
| 		CustomMessageBox::selectable(this, tr("Error"), errorMsg, QMessageBox::Warning)->show(); | ||||
| 		break; | ||||
| 	} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void MainWindow::on_actionChangeInstIcon_triggered() | ||||
| @@ -387,9 +394,10 @@ void MainWindow::on_actionDeleteInstance_triggered() | ||||
| { | ||||
| 	if (m_selectedInstance) | ||||
| 	{ | ||||
| 		int response = QMessageBox::question( | ||||
| 			this, "CAREFUL", QString("This is permanent! Are you sure?\nAbout to delete: ") + | ||||
| 								 m_selectedInstance->name()); | ||||
| 		auto response = CustomMessageBox::selectable(this, tr("CAREFUL"), | ||||
| 													 tr("This is permanent! Are you sure?\nAbout to delete: ") | ||||
| 													 + m_selectedInstance->name(), | ||||
| 													 QMessageBox::Question, QMessageBox::Yes | QMessageBox::No)->exec(); | ||||
| 		if (response == QMessageBox::Yes) | ||||
| 		{ | ||||
| 			m_selectedInstance->nuke(); | ||||
| @@ -626,7 +634,7 @@ void MainWindow::onGameUpdateComplete() | ||||
|  | ||||
| void MainWindow::onGameUpdateError(QString error) | ||||
| { | ||||
| 	QMessageBox::warning(this, "Error updating instance", error); | ||||
| 	CustomMessageBox::selectable(this, tr("Error updating instance"), error, QMessageBox::Warning)->show(); | ||||
| } | ||||
|  | ||||
| void MainWindow::launchInstance(BaseInstance *instance, LoginResponse response) | ||||
| @@ -695,9 +703,9 @@ void MainWindow::on_actionMakeDesktopShortcut_triggered() | ||||
| 						 QStringList() << "-dl" << QDir::currentPath() << "test", name, | ||||
| 						 "application-x-octet-stream"); | ||||
|  | ||||
| 	QMessageBox::warning( | ||||
| 		this, tr("Not useful"), | ||||
| 		tr("A Dummy Shortcut was created. it will not do anything productive")); | ||||
| 	CustomMessageBox::selectable(this, tr("Not useful"), | ||||
| 								 tr("A Dummy Shortcut was created. it will not do anything productive"), | ||||
| 								 QMessageBox::Warning)->show(); | ||||
| } | ||||
|  | ||||
| // BrowserDialog | ||||
| @@ -718,11 +726,11 @@ void MainWindow::on_actionChangeInstMCVersion_triggered() | ||||
| 	{ | ||||
| 		if (m_selectedInstance->versionIsCustom()) | ||||
| 		{ | ||||
| 			auto result = QMessageBox::warning( | ||||
| 				this, tr("Are you sure?"), | ||||
| 				tr("This will remove any library/version customization you did previously. " | ||||
| 				   "This includes things like Forge install and similar."), | ||||
| 				QMessageBox::Ok, QMessageBox::Abort); | ||||
| 			auto result = CustomMessageBox::selectable(this, tr("Are you sure?"), | ||||
| 										 tr("This will remove any library/version customization you did previously. " | ||||
| 											"This includes things like Forge install and similar."), | ||||
| 										 QMessageBox::Warning, QMessageBox::Ok, QMessageBox::Abort)->exec(); | ||||
|  | ||||
| 			if (result != QMessageBox::Ok) | ||||
| 				return; | ||||
| 		} | ||||
| @@ -853,10 +861,12 @@ void MainWindow::checkSetDefaultJava() | ||||
| 			java = std::dynamic_pointer_cast<JavaVersion>(vselect.selectedVersion()); | ||||
| 		else | ||||
| 		{ | ||||
| 			QMessageBox::warning(this, tr("Invalid version selected"), | ||||
| 								 tr("You didn't select a valid Java version, so MultiMC will " | ||||
| 									"select the default. " | ||||
| 									"You can change this in the settings dialog.")); | ||||
| 			CustomMessageBox::selectable(this, tr("Invalid version selected"), | ||||
| 										 tr("You didn't select a valid Java version, so MultiMC will " | ||||
| 											"select the default. " | ||||
| 											"You can change this in the settings dialog."), | ||||
| 										 QMessageBox::Warning)->show(); | ||||
|  | ||||
| 			JavaUtils ju; | ||||
| 			java = ju.GetDefaultJava(); | ||||
| 		} | ||||
|   | ||||
| @@ -3,7 +3,7 @@ | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  *  | ||||
|  * | ||||
|  *     http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
| @@ -19,19 +19,20 @@ | ||||
| #include "logic/JavaUtils.h" | ||||
| #include "gui/versionselectdialog.h" | ||||
| #include "gui/platform.h" | ||||
| #include "gui/CustomMessageBox.h" | ||||
| #include "logic/lists/JavaVersionList.h" | ||||
|  | ||||
| #include <settingsobject.h> | ||||
| #include <pathutils.h> | ||||
| #include <QFileDialog> | ||||
| #include <QMessageBox> | ||||
| #include <QDir> | ||||
|  | ||||
| SettingsDialog::SettingsDialog(QWidget *parent) : | ||||
| 	QDialog(parent), | ||||
| 	ui(new Ui::SettingsDialog) | ||||
| SettingsDialog::SettingsDialog(QWidget *parent) : QDialog(parent), ui(new Ui::SettingsDialog) | ||||
| { | ||||
|     MultiMCPlatform::fixWM_CLASS(this); | ||||
| 	MultiMCPlatform::fixWM_CLASS(this); | ||||
| 	ui->setupUi(this); | ||||
| 	 | ||||
|  | ||||
| 	loadSettings(MMC->settings().get()); | ||||
| 	updateCheckboxStuff(); | ||||
| } | ||||
| @@ -40,7 +41,7 @@ SettingsDialog::~SettingsDialog() | ||||
| { | ||||
| 	delete ui; | ||||
| } | ||||
| void SettingsDialog::showEvent ( QShowEvent* ev ) | ||||
| void SettingsDialog::showEvent(QShowEvent *ev) | ||||
| { | ||||
| 	QDialog::showEvent(ev); | ||||
| 	adjustSize(); | ||||
| @@ -49,31 +50,46 @@ void SettingsDialog::showEvent ( QShowEvent* ev ) | ||||
| void SettingsDialog::updateCheckboxStuff() | ||||
| { | ||||
| 	ui->windowWidthSpinBox->setEnabled(!ui->maximizedCheckBox->isChecked()); | ||||
| 	ui->windowHeightSpinBox->setEnabled(! ui->maximizedCheckBox->isChecked()); | ||||
| 	ui->windowHeightSpinBox->setEnabled(!ui->maximizedCheckBox->isChecked()); | ||||
| } | ||||
|  | ||||
| void SettingsDialog::on_instDirBrowseBtn_clicked() | ||||
| { | ||||
| 	QString dir = QFileDialog::getExistingDirectory(this, tr("Instance Directory"),  | ||||
| 													ui->instDirTextBox->text()); | ||||
| 	if (!dir.isEmpty()) | ||||
| 		ui->instDirTextBox->setText(dir); | ||||
| 	QString raw_dir = QFileDialog::getExistingDirectory(this, tr("Instance Directory"), | ||||
| 														ui->instDirTextBox->text()); | ||||
| 	QString cooked_dir = NormalizePath(raw_dir); | ||||
|  | ||||
| 	// do not allow current dir - it's dirty. Do not allow dirs that don't exist | ||||
| 	if (!cooked_dir.isEmpty() && QDir(cooked_dir).exists()) | ||||
| 	{ | ||||
| 		ui->instDirTextBox->setText(cooked_dir); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void SettingsDialog::on_modsDirBrowseBtn_clicked() | ||||
| { | ||||
| 	QString dir = QFileDialog::getExistingDirectory(this, tr("Mods Directory"),  | ||||
| 													ui->modsDirTextBox->text()); | ||||
| 	if (!dir.isEmpty()) | ||||
| 		ui->modsDirTextBox->setText(dir); | ||||
| 	QString raw_dir = QFileDialog::getExistingDirectory(this, tr("Mods Directory"), | ||||
| 														ui->modsDirTextBox->text()); | ||||
| 	QString cooked_dir = NormalizePath(raw_dir); | ||||
|  | ||||
| 	// do not allow current dir - it's dirty. Do not allow dirs that don't exist | ||||
| 	if (!cooked_dir.isEmpty() && QDir(cooked_dir).exists()) | ||||
| 	{ | ||||
| 		ui->modsDirTextBox->setText(cooked_dir); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void SettingsDialog::on_lwjglDirBrowseBtn_clicked() | ||||
| { | ||||
| 	QString dir = QFileDialog::getExistingDirectory(this, tr("LWJGL Directory"),  | ||||
| 													ui->lwjglDirTextBox->text()); | ||||
| 	if (!dir.isEmpty()) | ||||
| 		ui->lwjglDirTextBox->setText(dir); | ||||
| 	QString raw_dir = QFileDialog::getExistingDirectory(this, tr("LWJGL Directory"), | ||||
| 														ui->lwjglDirTextBox->text()); | ||||
| 	QString cooked_dir = NormalizePath(raw_dir); | ||||
|  | ||||
| 	// do not allow current dir - it's dirty. Do not allow dirs that don't exist | ||||
| 	if (!cooked_dir.isEmpty() && QDir(cooked_dir).exists()) | ||||
| 	{ | ||||
| 		ui->lwjglDirTextBox->setText(cooked_dir); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void SettingsDialog::on_compatModeCheckBox_clicked(bool checked) | ||||
| @@ -96,7 +112,7 @@ void SettingsDialog::on_buttonBox_accepted() | ||||
| void SettingsDialog::applySettings(SettingsObject *s) | ||||
| { | ||||
| 	// Special cases | ||||
| 	 | ||||
|  | ||||
| 	// Warn about dev builds. | ||||
| 	if (!ui->devBuildsCheckBox->isChecked()) | ||||
| 	{ | ||||
| @@ -104,46 +120,46 @@ void SettingsDialog::applySettings(SettingsObject *s) | ||||
| 	} | ||||
| 	else if (!s->get("UseDevBuilds").toBool()) | ||||
| 	{ | ||||
| 		int response = QMessageBox::question(this, tr("Development builds"),  | ||||
| 											 tr("Development builds contain experimental features " | ||||
| 											 "and may be unstable. Are you sure you want to enable them?")); | ||||
| 		auto response = CustomMessageBox::selectable(this, tr("Development builds"), | ||||
| 													 tr("Development builds contain experimental features " | ||||
| 														"and may be unstable. Are you sure you want to enable them?"), | ||||
| 													 QMessageBox::Question, QMessageBox::Yes | QMessageBox::No)->exec(); | ||||
| 		if (response == QMessageBox::Yes) | ||||
| 		{ | ||||
| 			s->set("UseDevBuilds", true); | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	 | ||||
|  | ||||
| 	// Updates | ||||
| 	s->set("AutoUpdate", ui->autoUpdateCheckBox->isChecked()); | ||||
| 	 | ||||
|  | ||||
| 	// Folders | ||||
| 	// TODO: Offer to move instances to new instance folder. | ||||
| 	s->set("InstanceDir", ui->instDirTextBox->text()); | ||||
| 	s->set("CentralModsDir", ui->modsDirTextBox->text()); | ||||
| 	s->set("LWJGLDir", ui->lwjglDirTextBox->text()); | ||||
| 	 | ||||
|  | ||||
| 	// Console | ||||
| 	s->set("ShowConsole", ui->showConsoleCheck->isChecked()); | ||||
| 	s->set("AutoCloseConsole", ui->autoCloseConsoleCheck->isChecked()); | ||||
| 	 | ||||
|  | ||||
| 	// Window Size | ||||
| 	s->set("LaunchMaximized", ui->maximizedCheckBox->isChecked()); | ||||
| 	s->set("MinecraftWinWidth", ui->windowWidthSpinBox->value()); | ||||
| 	s->set("MinecraftWinHeight", ui->windowHeightSpinBox->value()); | ||||
| 	 | ||||
|  | ||||
| 	// Auto Login | ||||
| 	s->set("AutoLogin", ui->autoLoginCheckBox->isChecked()); | ||||
| 	 | ||||
|  | ||||
| 	// Memory | ||||
| 	s->set("MinMemAlloc", ui->minMemSpinBox->value()); | ||||
| 	s->set("MaxMemAlloc", ui->maxMemSpinBox->value()); | ||||
| 	s->set("PermGen", ui->permGenSpinBox->value()); | ||||
| 	 | ||||
|  | ||||
| 	// Java Settings | ||||
| 	s->set("JavaPath", ui->javaPathTextBox->text()); | ||||
| 	s->set("JvmArgs", ui->jvmArgsTextBox->text()); | ||||
| 	 | ||||
|  | ||||
| 	// Custom Commands | ||||
| 	s->set("PreLaunchCommand", ui->preLaunchCmdTextBox->text()); | ||||
| 	s->set("PostExitCommand", ui->postExitCmdTextBox->text()); | ||||
| @@ -154,33 +170,33 @@ void SettingsDialog::loadSettings(SettingsObject *s) | ||||
| 	// Updates | ||||
| 	ui->autoUpdateCheckBox->setChecked(s->get("AutoUpdate").toBool()); | ||||
| 	ui->devBuildsCheckBox->setChecked(s->get("UseDevBuilds").toBool()); | ||||
| 	 | ||||
|  | ||||
| 	// Folders | ||||
| 	ui->instDirTextBox->setText(s->get("InstanceDir").toString()); | ||||
| 	ui->modsDirTextBox->setText(s->get("CentralModsDir").toString()); | ||||
| 	ui->lwjglDirTextBox->setText(s->get("LWJGLDir").toString()); | ||||
| 	 | ||||
|  | ||||
| 	// Console | ||||
| 	ui->showConsoleCheck->setChecked(s->get("ShowConsole").toBool()); | ||||
| 	ui->autoCloseConsoleCheck->setChecked(s->get("AutoCloseConsole").toBool()); | ||||
| 	 | ||||
|  | ||||
| 	// Window Size | ||||
| 	ui->maximizedCheckBox->setChecked(s->get("LaunchMaximized").toBool()); | ||||
| 	ui->windowWidthSpinBox->setValue(s->get("MinecraftWinWidth").toInt()); | ||||
| 	ui->windowHeightSpinBox->setValue(s->get("MinecraftWinHeight").toInt()); | ||||
| 	 | ||||
|  | ||||
| 	// Auto Login | ||||
| 	ui->autoLoginCheckBox->setChecked(s->get("AutoLogin").toBool()); | ||||
| 	 | ||||
|  | ||||
| 	// Memory | ||||
| 	ui->minMemSpinBox->setValue(s->get("MinMemAlloc").toInt()); | ||||
| 	ui->maxMemSpinBox->setValue(s->get("MaxMemAlloc").toInt()); | ||||
| 	ui->permGenSpinBox->setValue(s->get("PermGen").toInt()); | ||||
| 	 | ||||
|  | ||||
| 	// Java Settings | ||||
| 	ui->javaPathTextBox->setText(s->get("JavaPath").toString()); | ||||
| 	ui->jvmArgsTextBox->setText(s->get("JvmArgs").toString()); | ||||
| 	 | ||||
|  | ||||
| 	// Custom Commands | ||||
| 	ui->preLaunchCmdTextBox->setText(s->get("PreLaunchCommand").toString()); | ||||
| 	ui->postExitCmdTextBox->setText(s->get("PostExitCommand").toString()); | ||||
| @@ -204,7 +220,7 @@ void SettingsDialog::on_pushButton_clicked() | ||||
| void SettingsDialog::on_btnBrowse_clicked() | ||||
| { | ||||
| 	QString dir = QFileDialog::getOpenFileName(this, tr("Find Java executable")); | ||||
| 	if(!dir.isNull()) | ||||
| 	if (!dir.isNull()) | ||||
| 	{ | ||||
| 		ui->javaPathTextBox->setText(dir); | ||||
| 	} | ||||
|   | ||||
| @@ -34,7 +34,7 @@ | ||||
| const static int GROUP_FILE_FORMAT_VERSION = 1; | ||||
|  | ||||
| InstanceList::InstanceList(const QString &instDir, QObject *parent) | ||||
| 	: QAbstractListModel(parent), m_instDir("instances") | ||||
| 	: QAbstractListModel(parent), m_instDir(instDir) | ||||
| { | ||||
| } | ||||
|  | ||||
| @@ -196,8 +196,8 @@ void InstanceList::loadGroupList(QMap<QString, QString> &groupMap) | ||||
| 	if (error.error != QJsonParseError::NoError) | ||||
| 	{ | ||||
| 		QLOG_ERROR() << QString("Failed to parse instance group file: %1 at offset %2") | ||||
| 						   .arg(error.errorString(), QString::number(error.offset)) | ||||
| 						   .toUtf8(); | ||||
| 							.arg(error.errorString(), QString::number(error.offset)) | ||||
| 							.toUtf8(); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| @@ -269,7 +269,8 @@ InstanceList::InstListError InstanceList::loadList() | ||||
|  | ||||
| 	m_instances.clear(); | ||||
| 	QDir dir(m_instDir); | ||||
| 	QDirIterator iter(dir); | ||||
| 	QDirIterator iter(m_instDir, QDir::Dirs | QDir::NoDot | QDir::NoDotDot | QDir::Readable, | ||||
| 					  QDirIterator::FollowSymlinks); | ||||
| 	while (iter.hasNext()) | ||||
| 	{ | ||||
| 		QString subDir = iter.next(); | ||||
| @@ -340,7 +341,12 @@ void InstanceList::clear() | ||||
| 	endResetModel(); | ||||
| 	emit dataIsInvalid(); | ||||
| } | ||||
| ; | ||||
|  | ||||
| void InstanceList::on_InstFolderChanged(const Setting &setting, QVariant value) | ||||
| { | ||||
| 	m_instDir = value.toString(); | ||||
| 	loadList(); | ||||
| } | ||||
|  | ||||
| /// Add an instance. Triggers notifications, returns the new index | ||||
| int InstanceList::add(InstancePtr t) | ||||
|   | ||||
| @@ -3,7 +3,7 @@ | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  *  | ||||
|  * | ||||
|  *     http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
| @@ -29,19 +29,19 @@ class InstanceList : public QAbstractListModel | ||||
| { | ||||
| 	Q_OBJECT | ||||
| private: | ||||
| 	void loadGroupList(QMap<QString, QString> & groupList); | ||||
| 	void loadGroupList(QMap<QString, QString> &groupList); | ||||
| 	void saveGroupList(); | ||||
| 	 | ||||
|  | ||||
| public: | ||||
| 	explicit InstanceList(const QString &instDir, QObject *parent = 0); | ||||
| 	virtual ~InstanceList(); | ||||
| 	 | ||||
|  | ||||
| public: | ||||
| 	QModelIndex  index ( int row, int column = 0, const QModelIndex& parent = QModelIndex() ) const; | ||||
| 	int rowCount ( const QModelIndex& parent = QModelIndex() ) const; | ||||
| 	QVariant data ( const QModelIndex& index, int role ) const; | ||||
| 	Qt::ItemFlags flags ( const QModelIndex& index ) const; | ||||
| 	 | ||||
| 	QModelIndex index(int row, int column = 0, const QModelIndex &parent = QModelIndex()) const; | ||||
| 	int rowCount(const QModelIndex &parent = QModelIndex()) const; | ||||
| 	QVariant data(const QModelIndex &index, int role) const; | ||||
| 	Qt::ItemFlags flags(const QModelIndex &index) const; | ||||
|  | ||||
| 	enum AdditionalRoles | ||||
| 	{ | ||||
| 		InstancePointerRole = 0x34B1CB48 ///< Return pointer to real instance | ||||
| @@ -56,58 +56,69 @@ public: | ||||
| 		NoError = 0, | ||||
| 		UnknownError | ||||
| 	}; | ||||
| 	 | ||||
| 	QString instDir() const { return m_instDir; } | ||||
| 	 | ||||
|  | ||||
| 	QString instDir() const | ||||
| 	{ | ||||
| 		return m_instDir; | ||||
| 	} | ||||
|  | ||||
| 	/*! | ||||
| 	 * \brief Loads the instance list. Triggers notifications. | ||||
| 	 */ | ||||
| 	InstListError loadList(); | ||||
| 	 | ||||
|  | ||||
| 	/*! | ||||
| 	 * \brief Get the instance at index | ||||
| 	 */ | ||||
| 	InstancePtr at(int i) const | ||||
| 	{ | ||||
| 		return m_instances.at(i); | ||||
| 	}; | ||||
| 	 | ||||
| 	} | ||||
| 	; | ||||
|  | ||||
| 	/*! | ||||
| 	 * \brief Get the count of loaded instances | ||||
| 	 */ | ||||
| 	int count() const | ||||
| 	{ | ||||
| 		return m_instances.count(); | ||||
| 	}; | ||||
| 	 | ||||
| 	} | ||||
| 	; | ||||
|  | ||||
| 	/// Clear all instances. Triggers notifications. | ||||
| 	void clear(); | ||||
| 	 | ||||
|  | ||||
| 	/// Add an instance. Triggers notifications, returns the new index | ||||
| 	int add(InstancePtr t); | ||||
| 	 | ||||
|  | ||||
| 	/// Get an instance by ID | ||||
| 	InstancePtr getInstanceById (QString id); | ||||
| 	InstancePtr getInstanceById(QString id); | ||||
| signals: | ||||
| 	void dataIsInvalid(); | ||||
| 	 | ||||
| private slots: | ||||
| 	void propertiesChanged(BaseInstance * inst); | ||||
| 	void instanceNuked(BaseInstance * inst); | ||||
|  | ||||
| public | ||||
| slots: | ||||
| 	void on_InstFolderChanged(const Setting & setting, QVariant value); | ||||
|  | ||||
| private | ||||
| slots: | ||||
| 	void propertiesChanged(BaseInstance *inst); | ||||
| 	void instanceNuked(BaseInstance *inst); | ||||
| 	void groupChanged(); | ||||
|  | ||||
| private: | ||||
| 	int getInstIndex(BaseInstance * inst); | ||||
| 	int getInstIndex(BaseInstance *inst); | ||||
|  | ||||
| protected: | ||||
| 	QString m_instDir; | ||||
| 	QList< InstancePtr > m_instances; | ||||
| 	QList<InstancePtr> m_instances; | ||||
| }; | ||||
|  | ||||
| class InstanceProxyModel : public KCategorizedSortFilterProxyModel | ||||
| { | ||||
| public: | ||||
| 	explicit InstanceProxyModel ( QObject *parent = 0 ); | ||||
| 	explicit InstanceProxyModel(QObject *parent = 0); | ||||
|  | ||||
| protected: | ||||
| 	virtual bool subSortLessThan ( const QModelIndex& left, const QModelIndex& right ) const; | ||||
| 	virtual bool subSortLessThan(const QModelIndex &left, const QModelIndex &right) const; | ||||
| }; | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Petr Mrázek
					Petr Mrázek