diff options
author | Sky <git@bunnies.cc> | 2013-10-14 02:59:21 +0100 |
---|---|---|
committer | Sky <git@bunnies.cc> | 2013-10-14 03:00:06 +0100 |
commit | 40a2456646df96e0dd8731ab78cba920a734a8e3 (patch) | |
tree | c73b382b68c739ab1605eddc095f0cd9a4ca4cc7 | |
parent | 0ae8073d41de014beb8fd386cfb4713ad86c4766 (diff) | |
download | MultiMC-40a2456646df96e0dd8731ab78cba920a734a8e3.tar MultiMC-40a2456646df96e0dd8731ab78cba920a734a8e3.tar.gz MultiMC-40a2456646df96e0dd8731ab78cba920a734a8e3.tar.lz MultiMC-40a2456646df96e0dd8731ab78cba920a734a8e3.tar.xz MultiMC-40a2456646df96e0dd8731ab78cba920a734a8e3.zip |
Huge Java detection refactor, version dialogs on first run (no JavaPath set) and "auto detect" button
-rw-r--r-- | CMakeLists.txt | 2 | ||||
-rw-r--r-- | MultiMC.cpp | 23 | ||||
-rw-r--r-- | MultiMC.h | 4 | ||||
-rw-r--r-- | gui/mainwindow.cpp | 30 | ||||
-rw-r--r-- | gui/mainwindow.h | 3 | ||||
-rw-r--r-- | gui/settingsdialog.cpp | 15 | ||||
-rw-r--r-- | gui/settingsdialog.ui | 2 | ||||
-rw-r--r-- | gui/versionselectdialog.cpp | 16 | ||||
-rw-r--r-- | gui/versionselectdialog.h | 5 | ||||
-rw-r--r-- | logic/JavaUtils.cpp | 61 | ||||
-rw-r--r-- | logic/JavaUtils.h | 16 | ||||
-rw-r--r-- | logic/lists/JavaVersionList.cpp | 203 | ||||
-rw-r--r-- | logic/lists/JavaVersionList.h | 93 |
13 files changed, 422 insertions, 51 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 5503c5ca..64823772 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -302,6 +302,8 @@ logic/lists/LwjglVersionList.h logic/lists/LwjglVersionList.cpp logic/lists/ForgeVersionList.h logic/lists/ForgeVersionList.cpp +logic/lists/JavaVersionList.h +logic/lists/JavaVersionList.cpp # misc model/view logic/EnabledItemFilter.h diff --git a/MultiMC.cpp b/MultiMC.cpp index be1b86da..481bb0bb 100644 --- a/MultiMC.cpp +++ b/MultiMC.cpp @@ -5,8 +5,10 @@ #include <QNetworkAccessManager> #include <QTranslator> #include <QLibraryInfo> +#include <QMessageBox> #include "gui/mainwindow.h" +#include "gui/versionselectdialog.h" #include "logic/lists/InstanceList.h" #include "logic/lists/IconList.h" #include "logic/lists/LwjglVersionList.h" @@ -263,17 +265,6 @@ void MultiMC::initGlobalSettings() // Java Settings m_settings->registerSetting(new Setting("JavaPath", "")); - QString currentJavaPath = m_settings->get("JavaPath").toString(); - if(currentJavaPath.isEmpty()) - { - QLOG_INFO() << "Java path not set, attempting to set it automatically..."; - - JavaUtils jut; - auto javas = jut.FindJavaPaths(); - - m_settings->set("JavaPath", std::get<JI_PATH>(javas.at(0))); - } - m_settings->registerSetting(new Setting("JvmArgs", "")); // Custom Commands @@ -342,6 +333,15 @@ std::shared_ptr<MinecraftVersionList> MultiMC::minecraftlist() return m_minecraftlist; } +std::shared_ptr<JavaVersionList> MultiMC::javalist() +{ + if (!m_javalist) + { + m_javalist.reset(new JavaVersionList()); + } + return m_javalist; +} + int main(int argc, char *argv[]) { // initialize Qt @@ -350,6 +350,7 @@ int main(int argc, char *argv[]) // show main window MainWindow mainWin; mainWin.show(); + mainWin.checkSetDefaultJava(); switch (app.status()) { @@ -16,6 +16,7 @@ class InstanceList; class IconList; class QNetworkAccessManager; class ForgeVersionList; +class JavaVersionList; #if defined(MMC) #undef MMC @@ -75,6 +76,8 @@ public: std::shared_ptr<MinecraftVersionList> minecraftlist(); + std::shared_ptr<JavaVersionList> javalist(); + private: void initLogger(); @@ -95,6 +98,7 @@ private: std::shared_ptr<LWJGLVersionList> m_lwjgllist; std::shared_ptr<ForgeVersionList> m_forgelist; std::shared_ptr<MinecraftVersionList> m_minecraftlist; + std::shared_ptr<JavaVersionList> m_javalist; QsLogging::DestinationPtr m_fileDestination; QsLogging::DestinationPtr m_debugDestination; diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp index c726591d..06329140 100644 --- a/gui/mainwindow.cpp +++ b/gui/mainwindow.cpp @@ -53,6 +53,7 @@ #include "logic/lists/MinecraftVersionList.h" #include "logic/lists/LwjglVersionList.h" #include "logic/lists/IconList.h" +#include "logic/lists/JavaVersionList.h" #include "logic/net/LoginTask.h" #include "logic/BaseInstance.h" @@ -60,6 +61,7 @@ #include "logic/MinecraftProcess.h" #include "logic/OneSixAssets.h" #include "logic/OneSixUpdate.h" +#include "logic/JavaUtils.h" #include "logic/LegacyInstance.h" @@ -701,3 +703,31 @@ void MainWindow::instanceEnded() this->show(); ui->actionLaunchInstance->setEnabled(m_selectedInstance); } + +void MainWindow::checkSetDefaultJava() +{ + QString currentJavaPath = MMC->settings()->get("JavaPath").toString(); + if(currentJavaPath.isEmpty()) + { + QLOG_DEBUG() << "Java path not set, showing Java selection dialog..."; + + JavaVersionPtr java; + + VersionSelectDialog vselect(MMC->javalist().get(), tr("First run: select a Java version"), this, false); + vselect.setResizeOn(2); + vselect.exec(); + + if (!vselect.selectedVersion()) + { + 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.")); + + JavaUtils ju; + java = ju.GetDefaultJava(); + } + + java = std::dynamic_pointer_cast<JavaVersion>(vselect.selectedVersion()); + MMC->settings()->set("JavaPath", java->path); + } +} diff --git a/gui/mainwindow.h b/gui/mainwindow.h index 86f21113..dbf7c4c3 100644 --- a/gui/mainwindow.h +++ b/gui/mainwindow.h @@ -49,6 +49,8 @@ public: // Browser Dialog void openWebPage(QUrl url); + void checkSetDefaultJava(); + private slots: void onCatToggled(bool); @@ -128,7 +130,6 @@ protected: void setCatBackground(bool enabled); private: - Ui::MainWindow *ui; KCategoryDrawer *drawer; KCategorizedView *view; diff --git a/gui/settingsdialog.cpp b/gui/settingsdialog.cpp index 011925b7..a3347680 100644 --- a/gui/settingsdialog.cpp +++ b/gui/settingsdialog.cpp @@ -17,6 +17,8 @@ #include "settingsdialog.h" #include "ui_settingsdialog.h" #include "logic/JavaUtils.h" +#include "gui/versionselectdialog.h" +#include "logic/lists/JavaVersionList.h" #include <settingsobject.h> #include <QFileDialog> @@ -184,10 +186,17 @@ void SettingsDialog::loadSettings(SettingsObject *s) void SettingsDialog::on_pushButton_clicked() { - JavaUtils jut; - auto javas = jut.FindJavaPaths(); + JavaVersionPtr java; - ui->javaPathTextBox->setText(std::get<JI_PATH>(javas.at(0))); + 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<JavaVersion>(vselect.selectedVersion()); + ui->javaPathTextBox->setText(java->path); + } } void SettingsDialog::on_btnBrowse_clicked() diff --git a/gui/settingsdialog.ui b/gui/settingsdialog.ui index 0b7985f1..f8e78b4d 100644 --- a/gui/settingsdialog.ui +++ b/gui/settingsdialog.ui @@ -423,7 +423,7 @@ </sizepolicy> </property> <property name="text"> - <string>Auto-detect</string> + <string>Auto-detect...</string> </property> </widget> </item> diff --git a/gui/versionselectdialog.cpp b/gui/versionselectdialog.cpp index d975a7b4..900cd092 100644 --- a/gui/versionselectdialog.cpp +++ b/gui/versionselectdialog.cpp @@ -26,7 +26,7 @@ #include <logic/lists/BaseVersionList.h> #include <logic/tasks/Task.h> -VersionSelectDialog::VersionSelectDialog(BaseVersionList *vlist, QString title, QWidget *parent) +VersionSelectDialog::VersionSelectDialog(BaseVersionList *vlist, QString title, QWidget *parent, bool cancelable) : QDialog(parent), ui(new Ui::VersionSelectDialog) { ui->setupUi(this); @@ -40,7 +40,12 @@ VersionSelectDialog::VersionSelectDialog(BaseVersionList *vlist, QString title, ui->listView->setModel(m_proxyModel); ui->listView->header()->setSectionResizeMode(QHeaderView::ResizeToContents); - ui->listView->header()->setSectionResizeMode(0, QHeaderView::Stretch); + ui->listView->header()->setSectionResizeMode(resizeOnColumn, QHeaderView::Stretch); + + if(!cancelable) + { + ui->buttonBox->button(QDialogButtonBox::Cancel)->setEnabled(false); + } } VersionSelectDialog::~VersionSelectDialog() @@ -48,6 +53,13 @@ VersionSelectDialog::~VersionSelectDialog() delete ui; } +void VersionSelectDialog::setResizeOn(int column) +{ + ui->listView->header()->setSectionResizeMode(resizeOnColumn, QHeaderView::ResizeToContents); + resizeOnColumn = column; + ui->listView->header()->setSectionResizeMode(resizeOnColumn, QHeaderView::Stretch); +} + int VersionSelectDialog::exec() { QDialog::open(); diff --git a/gui/versionselectdialog.h b/gui/versionselectdialog.h index 4be048af..319caeca 100644 --- a/gui/versionselectdialog.h +++ b/gui/versionselectdialog.h @@ -33,7 +33,7 @@ class VersionSelectDialog : public QDialog Q_OBJECT public: - explicit VersionSelectDialog(BaseVersionList *vlist, QString title, QWidget *parent = 0); + explicit VersionSelectDialog(BaseVersionList *vlist, QString title, QWidget *parent = 0, bool cancelable = true); ~VersionSelectDialog(); virtual int exec(); @@ -44,6 +44,7 @@ public: BaseVersionPtr selectedVersion() const; void setFilter(int column, QString filter); + void setResizeOn(int column); private slots: void on_refreshButton_clicked(); @@ -53,6 +54,8 @@ private: BaseVersionList *m_vlist; QSortFilterProxyModel *m_proxyModel; + + int resizeOnColumn = 0; }; #endif // VERSIONSELECTDIALOG_H diff --git a/logic/JavaUtils.cpp b/logic/JavaUtils.cpp index 5cec35b6..c0630545 100644 --- a/logic/JavaUtils.cpp +++ b/logic/JavaUtils.cpp @@ -15,29 +15,37 @@ #include "JavaUtils.h" #include "pathutils.h" +#include "MultiMC.h" #include <QStringList> #include <QString> #include <QDir> +#include <QMessageBox> #include <logger/QsLog.h> +#include <gui/versionselectdialog.h> +#include <setting.h> JavaUtils::JavaUtils() { } -std::vector<java_install> JavaUtils::GetDefaultJava() +JavaVersionPtr JavaUtils::GetDefaultJava() { - std::vector<java_install> javas; - javas.push_back(std::make_tuple("java", "unknown", "java", false)); + JavaVersionPtr javaVersion(new JavaVersion()); - return javas; + javaVersion->id = "java"; + javaVersion->arch = "unknown"; + javaVersion->path = "java"; + javaVersion->recommended = false; + + return javaVersion; } #if WINDOWS -std::vector<java_install> JavaUtils::FindJavaFromRegistryKey(DWORD keyType, QString keyName) +QList<JavaVersionPtr> JavaUtils::FindJavaFromRegistryKey(DWORD keyType, QString keyName) { - std::vector<java_install> javas; + QList<JavaVersionPtr> javas; QString archType = "unknown"; if(keyType == KEY_WOW64_64KEY) archType = "64"; @@ -87,7 +95,14 @@ std::vector<java_install> JavaUtils::FindJavaFromRegistryKey(DWORD keyType, QStr value = new char[valueSz]; RegQueryValueEx(newKey, "JavaHome", NULL, NULL, (BYTE*)value, &valueSz); - javas.push_back(std::make_tuple(subKeyName, archType, QDir(PathCombine(value, "bin")).absoluteFilePath("java.exe"), (recommended == subKeyName))); + // Now, we construct the version object and add it to the list. + JavaVersionPtr javaVersion(new JavaVersion()); + + javaVersion->id = subKeyName; + javaVersion->arch = archType; + javaVersion->path = QDir(PathCombine(value, "bin")).absoluteFilePath("java.exe"); + javaVersion->recommended = (recommended == subKeyName); + javas.append(javaVersion); } RegCloseKey(newKey); @@ -102,23 +117,25 @@ std::vector<java_install> JavaUtils::FindJavaFromRegistryKey(DWORD keyType, QStr return javas; } -std::vector<java_install> JavaUtils::FindJavaPaths() -{ - std::vector<java_install> JRE64s = this->FindJavaFromRegistryKey(KEY_WOW64_64KEY, "SOFTWARE\\JavaSoft\\Java Runtime Environment"); - std::vector<java_install> JDK64s = this->FindJavaFromRegistryKey(KEY_WOW64_64KEY, "SOFTWARE\\JavaSoft\\Java Development Kit"); - std::vector<java_install> JRE32s = this->FindJavaFromRegistryKey(KEY_WOW64_32KEY, "SOFTWARE\\JavaSoft\\Java Runtime Environment"); - std::vector<java_install> JDK32s = this->FindJavaFromRegistryKey(KEY_WOW64_32KEY, "SOFTWARE\\JavaSoft\\Java Development Kit"); - - std::vector<java_install> javas; - javas.insert(javas.end(), JRE64s.begin(), JRE64s.end()); - javas.insert(javas.end(), JDK64s.begin(), JDK64s.end()); - javas.insert(javas.end(), JRE32s.begin(), JRE32s.end()); - javas.insert(javas.end(), JDK32s.begin(), JDK32s.end()); +QList<JavaVersionPtr> JavaUtils::FindJavaPaths() +{ + QList<JavaVersionPtr> javas; + + QList<JavaVersionPtr> JRE64s = this->FindJavaFromRegistryKey(KEY_WOW64_64KEY, "SOFTWARE\\JavaSoft\\Java Runtime Environment"); + QList<JavaVersionPtr> JDK64s = this->FindJavaFromRegistryKey(KEY_WOW64_64KEY, "SOFTWARE\\JavaSoft\\Java Development Kit"); + QList<JavaVersionPtr> JRE32s = this->FindJavaFromRegistryKey(KEY_WOW64_32KEY, "SOFTWARE\\JavaSoft\\Java Runtime Environment"); + QList<JavaVersionPtr> JDK32s = this->FindJavaFromRegistryKey(KEY_WOW64_32KEY, "SOFTWARE\\JavaSoft\\Java Development Kit"); + + javas.append(JRE64s); + javas.append(JDK64s); + javas.append(JRE32s); + javas.append(JDK32s); if(javas.size() <= 0) { QLOG_WARN() << "Failed to find Java in the Windows registry - defaulting to \"java\""; - return this->GetDefaultJava(); + javas.append(this->GetDefaultJava()); + return javas; } QLOG_INFO() << "Found the following Java installations (64 -> 32, JRE -> JDK): "; @@ -126,8 +143,8 @@ std::vector<java_install> JavaUtils::FindJavaPaths() for(auto &java : javas) { QString sRec; - if(std::get<JI_REC>(java)) sRec = "(Recommended)"; - QLOG_INFO() << std::get<JI_ID>(java) << std::get<JI_ARCH>(java) << " at " << std::get<JI_PATH>(java) << sRec; + if(java->recommended) sRec = "(Recommended)"; + QLOG_INFO() << java->id << java->arch << " at " << java->path << sRec; } return javas; diff --git a/logic/JavaUtils.h b/logic/JavaUtils.h index 63daac12..e4f777d0 100644 --- a/logic/JavaUtils.h +++ b/logic/JavaUtils.h @@ -16,29 +16,25 @@ #pragma once #include <QStringList> - +#include <QWidget> +#include <logic/lists/JavaVersionList.h> #include "osutils.h" #if WINDOWS #include <windows.h> #endif -#define JI_ID 0 -#define JI_ARCH 1 -#define JI_PATH 2 -#define JI_REC 3 -typedef std::tuple<QString, QString, QString, bool> java_install; - class JavaUtils { public: JavaUtils(); - std::vector<java_install> FindJavaPaths(); + QList<JavaVersionPtr> FindJavaPaths(); + JavaVersionPtr GetDefaultJava(); private: - std::vector<java_install> GetDefaultJava(); + #if WINDOWS - std::vector<java_install> FindJavaFromRegistryKey(DWORD keyType, QString keyName); + QList<JavaVersionPtr> FindJavaFromRegistryKey(DWORD keyType, QString keyName); #endif }; diff --git a/logic/lists/JavaVersionList.cpp b/logic/lists/JavaVersionList.cpp new file mode 100644 index 00000000..5389c4cc --- /dev/null +++ b/logic/lists/JavaVersionList.cpp @@ -0,0 +1,203 @@ +/* Copyright 2013 MultiMC Contributors + * + * 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 + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "JavaVersionList.h" +#include "MultiMC.h" + +#include <QtNetwork> +#include <QtXml> +#include <QRegExp> + +#include <logger/QsLog.h> +#include <logic/JavaUtils.h> + +JavaVersionList::JavaVersionList(QObject *parent) : BaseVersionList(parent) +{ +} + +Task *JavaVersionList::getLoadTask() +{ + return new JavaListLoadTask(this); +} + + +const BaseVersionPtr JavaVersionList::at(int i) const +{ + return m_vlist.at(i); +} + +bool JavaVersionList::isLoaded() +{ + return m_loaded; +} + +int JavaVersionList::count() const +{ + return m_vlist.count(); +} + +int JavaVersionList::columnCount(const QModelIndex &parent) const +{ + return 4; +} + +QVariant JavaVersionList::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + return QVariant(); + + if (index.row() > count()) + return QVariant(); + + auto version = std::dynamic_pointer_cast<JavaVersion>(m_vlist[index.row()]); + switch (role) + { + case Qt::DisplayRole: + switch (index.column()) + { + case 0: + return version->id; + + case 1: + return version->arch; + + case 2: + return version->path; + + case 3: + return version->recommended ? tr("Yes") : tr("No"); + + default: + return QVariant(); + } + + case Qt::ToolTipRole: + return version->descriptor(); + + case VersionPointerRole: + return qVariantFromValue(m_vlist[index.row()]); + + default: + return QVariant(); + } +} + +QVariant JavaVersionList::headerData(int section, Qt::Orientation orientation, int role) const +{ + switch (role) + { + case Qt::DisplayRole: + switch (section) + { + case 0: + return "Version"; + + case 1: + return "Arch"; + + case 2: + return "Path"; + + case 3: + return "Recommended"; + + default: + return QVariant(); + } + + case Qt::ToolTipRole: + switch (section) + { + case 0: + return "The name of the version."; + + case 1: + return "The architecture this version is for."; + + case 2: + return "Path to this Java version."; + + case 3: + return "Whether the version is recommended or not."; + + default: + return QVariant(); + } + + default: + return QVariant(); + } +} + +BaseVersionPtr JavaVersionList::getTopRecommended() const +{ + for (int i = 0; i < m_vlist.length(); i++) + { + auto ver = std::dynamic_pointer_cast<JavaVersion>(m_vlist.at(i)); + if (ver->recommended) + { + return m_vlist.at(i); + } + } + return BaseVersionPtr(); +} + +void JavaVersionList::updateListData(QList<BaseVersionPtr> versions) +{ + beginResetModel(); + m_vlist = versions; + m_loaded = true; + endResetModel(); + // NOW SORT!! + // sort(); +} + +void JavaVersionList::sort() +{ + // NO-OP for now +} + +JavaListLoadTask::JavaListLoadTask(JavaVersionList *vlist) +{ + m_list = vlist; + m_currentRecommended = NULL; +} + +JavaListLoadTask::~JavaListLoadTask() +{ +} + +void JavaListLoadTask::executeTask() +{ + setStatus("Detecting Java installations..."); + + JavaUtils ju; + QList<JavaVersionPtr> javas = ju.FindJavaPaths(); + + QList<BaseVersionPtr> javas_bvp; + for(int i = 0; i < javas.length(); i++) + { + BaseVersionPtr java = std::dynamic_pointer_cast<BaseVersion>(javas.at(i)); + + if(java) + { + javas_bvp.append(java); + } + } + + m_list->updateListData(javas_bvp); + + emitSucceeded(); +} diff --git a/logic/lists/JavaVersionList.h b/logic/lists/JavaVersionList.h new file mode 100644 index 00000000..23bccfe4 --- /dev/null +++ b/logic/lists/JavaVersionList.h @@ -0,0 +1,93 @@ +/* Copyright 2013 MultiMC Contributors + * + * 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 + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include <QObject> +#include <QAbstractListModel> +#include <QSharedPointer> + +#include "BaseVersionList.h" +#include "logic/tasks/Task.h" + +class JavaListLoadTask; + +struct JavaVersion : public BaseVersion +{ + virtual QString descriptor() + { + return id; + } + + virtual QString name() + { + return id; + } + + virtual QString typeString() const + { + return arch; + } + + QString id; + QString arch; + QString path; + bool recommended; +}; + +typedef std::shared_ptr<JavaVersion> JavaVersionPtr; + +class JavaVersionList : public BaseVersionList +{ + Q_OBJECT +public: + explicit JavaVersionList(QObject *parent = 0); + + virtual Task *getLoadTask(); + virtual bool isLoaded(); + virtual const BaseVersionPtr at(int i) const; + virtual int count() const; + virtual void sort(); + + virtual BaseVersionPtr getTopRecommended() const; + + virtual QVariant data(const QModelIndex &index, int role) const; + virtual QVariant headerData(int section, Qt::Orientation orientation, + int role) const; + virtual int columnCount(const QModelIndex &parent) const; + +public slots: + virtual void updateListData(QList<BaseVersionPtr> versions); + +protected: + QList<BaseVersionPtr> m_vlist; + + bool m_loaded = false; +}; + +class JavaListLoadTask : public Task +{ + Q_OBJECT + +public: + explicit JavaListLoadTask(JavaVersionList *vlist); + ~JavaListLoadTask(); + + virtual void executeTask(); + +protected: + JavaVersionList *m_list; + JavaVersion *m_currentRecommended; +}; |