From 8a3a0f5a529a95c7511436051b63887dff158c50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Thu, 8 May 2014 21:20:10 +0200 Subject: Reorganize logic code. --- logic/java/JavaChecker.cpp | 124 +++++++++++++++++++++ logic/java/JavaChecker.h | 42 +++++++ logic/java/JavaCheckerJob.cpp | 47 ++++++++ logic/java/JavaCheckerJob.h | 100 +++++++++++++++++ logic/java/JavaUtils.cpp | 221 +++++++++++++++++++++++++++++++++++++ logic/java/JavaUtils.h | 43 ++++++++ logic/java/JavaVersionList.cpp | 241 +++++++++++++++++++++++++++++++++++++++++ logic/java/JavaVersionList.h | 96 ++++++++++++++++ 8 files changed, 914 insertions(+) create mode 100644 logic/java/JavaChecker.cpp create mode 100644 logic/java/JavaChecker.h create mode 100644 logic/java/JavaCheckerJob.cpp create mode 100644 logic/java/JavaCheckerJob.h create mode 100644 logic/java/JavaUtils.cpp create mode 100644 logic/java/JavaUtils.h create mode 100644 logic/java/JavaVersionList.cpp create mode 100644 logic/java/JavaVersionList.h (limited to 'logic/java') diff --git a/logic/java/JavaChecker.cpp b/logic/java/JavaChecker.cpp new file mode 100644 index 00000000..b87ee3d5 --- /dev/null +++ b/logic/java/JavaChecker.cpp @@ -0,0 +1,124 @@ +#include "JavaChecker.h" +#include "MultiMC.h" +#include +#include +#include +#include +#include + +JavaChecker::JavaChecker(QObject *parent) : QObject(parent) +{ +} + +void JavaChecker::performCheck() +{ + QString checkerJar = PathCombine(MMC->bin(), "jars", "JavaCheck.jar"); + + QStringList args = {"-jar", checkerJar}; + + process.reset(new QProcess()); + process->setArguments(args); + process->setProgram(path); + process->setProcessChannelMode(QProcess::SeparateChannels); + QLOG_DEBUG() << "Running java checker!"; + QLOG_DEBUG() << "Java: " + path; + QLOG_DEBUG() << "Args: {" + args.join("|") + "}"; + + connect(process.get(), SIGNAL(finished(int, QProcess::ExitStatus)), this, + SLOT(finished(int, QProcess::ExitStatus))); + connect(process.get(), SIGNAL(error(QProcess::ProcessError)), this, + SLOT(error(QProcess::ProcessError))); + connect(&killTimer, SIGNAL(timeout()), SLOT(timeout())); + killTimer.setSingleShot(true); + killTimer.start(5000); + process->start(); +} + +void JavaChecker::finished(int exitcode, QProcess::ExitStatus status) +{ + killTimer.stop(); + QProcessPtr _process; + _process.swap(process); + + JavaCheckResult result; + { + result.path = path; + result.id = id; + } + QLOG_DEBUG() << "Java checker finished with status " << status << " exit code " << exitcode; + + if (status == QProcess::CrashExit || exitcode == 1) + { + QLOG_DEBUG() << "Java checker failed!"; + emit checkFinished(result); + return; + } + + bool success = true; + QString p_stdout = _process->readAllStandardOutput(); + QLOG_DEBUG() << p_stdout; + + QMap results; + QStringList lines = p_stdout.split("\n", QString::SkipEmptyParts); + for(QString line : lines) + { + line = line.trimmed(); + + auto parts = line.split('=', QString::SkipEmptyParts); + if(parts.size() != 2 || parts[0].isEmpty() || parts[1].isEmpty()) + { + success = false; + } + else + { + results.insert(parts[0], parts[1]); + } + } + + if(!results.contains("os.arch") || !results.contains("java.version") || !success) + { + QLOG_DEBUG() << "Java checker failed - couldn't extract required information."; + emit checkFinished(result); + return; + } + + auto os_arch = results["os.arch"]; + auto java_version = results["java.version"]; + bool is_64 = os_arch == "x86_64" || os_arch == "amd64"; + + + result.valid = true; + result.is_64bit = is_64; + result.mojangPlatform = is_64 ? "64" : "32"; + result.realPlatform = os_arch; + result.javaVersion = java_version; + QLOG_DEBUG() << "Java checker succeeded."; + emit checkFinished(result); +} + +void JavaChecker::error(QProcess::ProcessError err) +{ + if(err == QProcess::FailedToStart) + { + killTimer.stop(); + QLOG_DEBUG() << "Java checker has failed to start."; + JavaCheckResult result; + { + result.path = path; + result.id = id; + } + + emit checkFinished(result); + return; + } +} + +void JavaChecker::timeout() +{ + // NO MERCY. NO ABUSE. + if(process) + { + QLOG_DEBUG() << "Java checker has been killed by timeout."; + process->kill(); + } +} diff --git a/logic/java/JavaChecker.h b/logic/java/JavaChecker.h new file mode 100644 index 00000000..e19895f7 --- /dev/null +++ b/logic/java/JavaChecker.h @@ -0,0 +1,42 @@ +#pragma once +#include +#include +#include + +class JavaChecker; + + +struct JavaCheckResult +{ + QString path; + QString mojangPlatform; + QString realPlatform; + QString javaVersion; + bool valid = false; + bool is_64bit = false; + int id; +}; + +typedef std::shared_ptr QProcessPtr; +typedef std::shared_ptr JavaCheckerPtr; +class JavaChecker : public QObject +{ + Q_OBJECT +public: + explicit JavaChecker(QObject *parent = 0); + void performCheck(); + + QString path; + int id; + +signals: + void checkFinished(JavaCheckResult result); +private: + QProcessPtr process; + QTimer killTimer; +public +slots: + void timeout(); + void finished(int exitcode, QProcess::ExitStatus); + void error(QProcess::ProcessError); +}; diff --git a/logic/java/JavaCheckerJob.cpp b/logic/java/JavaCheckerJob.cpp new file mode 100644 index 00000000..b0aea758 --- /dev/null +++ b/logic/java/JavaCheckerJob.cpp @@ -0,0 +1,47 @@ +/* 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 "JavaCheckerJob.h" +#include "pathutils.h" +#include "MultiMC.h" + +#include "logger/QsLog.h" + +void JavaCheckerJob::partFinished(JavaCheckResult result) +{ + num_finished++; + QLOG_INFO() << m_job_name.toLocal8Bit() << "progress:" << num_finished << "/" + << javacheckers.size(); + emit progress(num_finished, javacheckers.size()); + + javaresults.replace(result.id, result); + + if (num_finished == javacheckers.size()) + { + emit finished(javaresults); + } +} + +void JavaCheckerJob::start() +{ + QLOG_INFO() << m_job_name.toLocal8Bit() << " started."; + m_running = true; + for (auto iter : javacheckers) + { + javaresults.append(JavaCheckResult()); + connect(iter.get(), SIGNAL(checkFinished(JavaCheckResult)), SLOT(partFinished(JavaCheckResult))); + iter->performCheck(); + } +} diff --git a/logic/java/JavaCheckerJob.h b/logic/java/JavaCheckerJob.h new file mode 100644 index 00000000..132a92d4 --- /dev/null +++ b/logic/java/JavaCheckerJob.h @@ -0,0 +1,100 @@ +/* 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 +#include +#include "JavaChecker.h" +#include "logic/tasks/ProgressProvider.h" + +class JavaCheckerJob; +typedef std::shared_ptr JavaCheckerJobPtr; + +class JavaCheckerJob : public ProgressProvider +{ + Q_OBJECT +public: + explicit JavaCheckerJob(QString job_name) : ProgressProvider(), m_job_name(job_name) {}; + + bool addJavaCheckerAction(JavaCheckerPtr base) + { + javacheckers.append(base); + total_progress++; + // if this is already running, the action needs to be started right away! + if (isRunning()) + { + emit progress(current_progress, total_progress); + connect(base.get(), SIGNAL(checkFinished(JavaCheckResult)), SLOT(partFinished(JavaCheckResult))); + + base->performCheck(); + } + return true; + } + + JavaCheckerPtr operator[](int index) + { + return javacheckers[index]; + } + ; + JavaCheckerPtr first() + { + if (javacheckers.size()) + return javacheckers[0]; + return JavaCheckerPtr(); + } + int size() const + { + return javacheckers.size(); + } + virtual void getProgress(qint64 ¤t, qint64 &total) + { + current = current_progress; + total = total_progress; + } + ; + virtual QString getStatus() const + { + return m_job_name; + } + ; + virtual bool isRunning() const + { + return m_running; + } + ; + +signals: + void started(); + void progress(int current, int total); + void finished(QList); +public +slots: + virtual void start(); + // FIXME: implement + virtual void abort() {}; +private +slots: + void partFinished(JavaCheckResult result); + +private: + QString m_job_name; + QList javacheckers; + QList javaresults; + qint64 current_progress = 0; + qint64 total_progress = 0; + int num_finished = 0; + bool m_running = false; +}; diff --git a/logic/java/JavaUtils.cpp b/logic/java/JavaUtils.cpp new file mode 100644 index 00000000..1be93a9b --- /dev/null +++ b/logic/java/JavaUtils.cpp @@ -0,0 +1,221 @@ +/* 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 +#include +#include +#include + +#include +#include + +#include "MultiMC.h" + +#include "logger/QsLog.h" +#include "logic/java/JavaUtils.h" +#include "logic/java/JavaCheckerJob.h" +#include "logic/java/JavaVersionList.h" + +JavaUtils::JavaUtils() +{ +} + +JavaVersionPtr JavaUtils::MakeJavaPtr(QString path, QString id, QString arch) +{ + JavaVersionPtr javaVersion(new JavaVersion()); + + javaVersion->id = id; + javaVersion->arch = arch; + javaVersion->path = path; + + return javaVersion; +} + +JavaVersionPtr JavaUtils::GetDefaultJava() +{ + JavaVersionPtr javaVersion(new JavaVersion()); + + javaVersion->id = "java"; + javaVersion->arch = "unknown"; + javaVersion->path = "java"; + + return javaVersion; +} + +#if WINDOWS +QList JavaUtils::FindJavaFromRegistryKey(DWORD keyType, QString keyName) +{ + QList javas; + + QString archType = "unknown"; + if (keyType == KEY_WOW64_64KEY) + archType = "64"; + else if (keyType == KEY_WOW64_32KEY) + archType = "32"; + + HKEY jreKey; + if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, keyName.toStdString().c_str(), 0, + KEY_READ | keyType | KEY_ENUMERATE_SUB_KEYS, &jreKey) == ERROR_SUCCESS) + { + // Read the current type version from the registry. + // This will be used to find any key that contains the JavaHome value. + char *value = new char[0]; + DWORD valueSz = 0; + if (RegQueryValueExA(jreKey, "CurrentVersion", NULL, NULL, (BYTE *)value, &valueSz) == + ERROR_MORE_DATA) + { + value = new char[valueSz]; + RegQueryValueExA(jreKey, "CurrentVersion", NULL, NULL, (BYTE *)value, &valueSz); + } + + QString recommended = value; + + TCHAR subKeyName[255]; + DWORD subKeyNameSize, numSubKeys, retCode; + + // Get the number of subkeys + RegQueryInfoKey(jreKey, NULL, NULL, NULL, &numSubKeys, NULL, NULL, NULL, NULL, NULL, + NULL, NULL); + + // Iterate until RegEnumKeyEx fails + if (numSubKeys > 0) + { + for (int i = 0; i < numSubKeys; i++) + { + subKeyNameSize = 255; + retCode = RegEnumKeyEx(jreKey, i, subKeyName, &subKeyNameSize, NULL, NULL, NULL, + NULL); + if (retCode == ERROR_SUCCESS) + { + // Now open the registry key for the version that we just got. + QString newKeyName = keyName + "\\" + subKeyName; + + HKEY newKey; + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, newKeyName.toStdString().c_str(), 0, + KEY_READ | KEY_WOW64_64KEY, &newKey) == ERROR_SUCCESS) + { + // Read the JavaHome value to find where Java is installed. + value = new char[0]; + valueSz = 0; + if (RegQueryValueEx(newKey, "JavaHome", NULL, NULL, (BYTE *)value, + &valueSz) == ERROR_MORE_DATA) + { + value = new char[valueSz]; + RegQueryValueEx(newKey, "JavaHome", NULL, NULL, (BYTE *)value, + &valueSz); + + // 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"); + javas.append(javaVersion); + } + + RegCloseKey(newKey); + } + } + } + } + + RegCloseKey(jreKey); + } + + return javas; +} + +QList JavaUtils::FindJavaPaths() +{ + QList java_candidates; + + QList JRE64s = this->FindJavaFromRegistryKey( + KEY_WOW64_64KEY, "SOFTWARE\\JavaSoft\\Java Runtime Environment"); + QList JDK64s = this->FindJavaFromRegistryKey( + KEY_WOW64_64KEY, "SOFTWARE\\JavaSoft\\Java Development Kit"); + QList JRE32s = this->FindJavaFromRegistryKey( + KEY_WOW64_32KEY, "SOFTWARE\\JavaSoft\\Java Runtime Environment"); + QList JDK32s = this->FindJavaFromRegistryKey( + KEY_WOW64_32KEY, "SOFTWARE\\JavaSoft\\Java Development Kit"); + + java_candidates.append(JRE64s); + java_candidates.append(MakeJavaPtr("C:/Program Files/Java/jre7/bin/java.exe")); + java_candidates.append(MakeJavaPtr("C:/Program Files/Java/jre6/bin/java.exe")); + java_candidates.append(JDK64s); + java_candidates.append(JRE32s); + java_candidates.append(MakeJavaPtr("C:/Program Files (x86)/Java/jre7/bin/java.exe")); + java_candidates.append(MakeJavaPtr("C:/Program Files (x86)/Java/jre6/bin/java.exe")); + java_candidates.append(JDK32s); + java_candidates.append(MakeJavaPtr(this->GetDefaultJava()->path)); + + QList candidates; + for(JavaVersionPtr java_candidate : java_candidates) + { + if(!candidates.contains(java_candidate->path)) + { + candidates.append(java_candidate->path); + } + } + + return candidates; +} + +#elif OSX +QList JavaUtils::FindJavaPaths() +{ + QList javas; + javas.append(this->GetDefaultJava()->path); + javas.append("/Applications/Xcode.app/Contents/Applications/Application Loader.app/Contents/MacOS/itms/java/bin/java"); + javas.append("/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/bin/java"); + javas.append("/System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/java"); + QDir libraryJVMDir("/Library/Java/JavaVirtualMachines/"); + QStringList libraryJVMJavas = libraryJVMDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot); + foreach (const QString &java, libraryJVMJavas) { + javas.append(libraryJVMDir.absolutePath() + "/" + java + "/Contents/Home/bin/java"); + javas.append(libraryJVMDir.absolutePath() + "/" + java + "/Contents/Home/jre/bin/java"); + } + QDir systemLibraryJVMDir("/System/Library/Java/JavaVirtualMachines/"); + QStringList systemLibraryJVMJavas = systemLibraryJVMDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot); + foreach (const QString &java, systemLibraryJVMJavas) { + javas.append(systemLibraryJVMDir.absolutePath() + "/" + java + "/Contents/Home/bin/java"); + javas.append(systemLibraryJVMDir.absolutePath() + "/" + java + "/Contents/Commands/java"); + } + return javas; +} + +#elif LINUX +QList JavaUtils::FindJavaPaths() +{ + QLOG_INFO() << "Linux Java detection incomplete - defaulting to \"java\""; + + QList javas; + javas.append(this->GetDefaultJava()->path); + javas.append("/opt/java/bin/java"); + javas.append("/usr/bin/java"); + + return javas; +} +#else +QList JavaUtils::FindJavaPaths() +{ + QLOG_INFO() << "Unknown operating system build - defaulting to \"java\""; + + QList javas; + javas.append(this->GetDefaultJava()->path); + + return javas; +} +#endif diff --git a/logic/java/JavaUtils.h b/logic/java/JavaUtils.h new file mode 100644 index 00000000..af92100f --- /dev/null +++ b/logic/java/JavaUtils.h @@ -0,0 +1,43 @@ +/* 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 +#include + +#include +#include "JavaCheckerJob.h" +#include "JavaChecker.h" +#include "JavaVersionList.h" + +#if WINDOWS +#include +#endif + +class JavaUtils : public QObject +{ + Q_OBJECT +public: + JavaUtils(); + + JavaVersionPtr MakeJavaPtr(QString path, QString id = "unknown", QString arch = "unknown"); + QList FindJavaPaths(); + JavaVersionPtr GetDefaultJava(); + +#if WINDOWS + QList FindJavaFromRegistryKey(DWORD keyType, QString keyName); +#endif +}; diff --git a/logic/java/JavaVersionList.cpp b/logic/java/JavaVersionList.cpp new file mode 100644 index 00000000..dcb6ced6 --- /dev/null +++ b/logic/java/JavaVersionList.cpp @@ -0,0 +1,241 @@ +/* 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 +#include +#include + +#include "MultiMC.h" +#include "logger/QsLog.h" + +#include "logic/java/JavaVersionList.h" +#include "logic/java/JavaCheckerJob.h" +#include "logic/java/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 3; +} + +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(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; + + 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"; + + 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."; + + default: + return QVariant(); + } + + default: + return QVariant(); + } +} + +BaseVersionPtr JavaVersionList::getTopRecommended() const +{ + auto first = m_vlist.first(); + if(first != nullptr) + { + return first; + } + else + { + return BaseVersionPtr(); + } +} + +void JavaVersionList::updateListData(QList versions) +{ + beginResetModel(); + m_vlist = versions; + m_loaded = true; + endResetModel(); + // NOW SORT!! + // sort(); +} + +void JavaVersionList::sort() +{ + // NO-OP for now +} + +JavaListLoadTask::JavaListLoadTask(JavaVersionList *vlist) : Task() +{ + m_list = vlist; + m_currentRecommended = NULL; +} + +JavaListLoadTask::~JavaListLoadTask() +{ +} + +void JavaListLoadTask::executeTask() +{ + setStatus(tr("Detecting Java installations...")); + + JavaUtils ju; + QList candidate_paths = ju.FindJavaPaths(); + + m_job = std::shared_ptr(new JavaCheckerJob("Java detection")); + connect(m_job.get(), SIGNAL(finished(QList)), this, SLOT(javaCheckerFinished(QList))); + connect(m_job.get(), SIGNAL(progress(int, int)), this, SLOT(checkerProgress(int, int))); + + QLOG_DEBUG() << "Probing the following Java paths: "; + int id = 0; + for(QString candidate : candidate_paths) + { + QLOG_DEBUG() << " " << candidate; + + auto candidate_checker = new JavaChecker(); + candidate_checker->path = candidate; + candidate_checker->id = id; + m_job->addJavaCheckerAction(JavaCheckerPtr(candidate_checker)); + + id++; + } + + m_job->start(); +} + +void JavaListLoadTask::checkerProgress(int current, int total) +{ + float progress = (current * 100.0) / total; + this->setProgress((int) progress); +} + +void JavaListLoadTask::javaCheckerFinished(QList results) +{ + QList candidates; + + QLOG_DEBUG() << "Found the following valid Java installations:"; + for(JavaCheckResult result : results) + { + if(result.valid) + { + JavaVersionPtr javaVersion(new JavaVersion()); + + javaVersion->id = result.javaVersion; + javaVersion->arch = result.mojangPlatform; + javaVersion->path = result.path; + candidates.append(javaVersion); + + QLOG_DEBUG() << " " << javaVersion->id << javaVersion->arch << javaVersion->path; + } + } + + QList javas_bvp; + for (auto java : candidates) + { + //QLOG_INFO() << java->id << java->arch << " at " << java->path; + BaseVersionPtr bp_java = std::dynamic_pointer_cast(java); + + if (bp_java) + { + javas_bvp.append(java); + } + } + + m_list->updateListData(javas_bvp); + emitSucceeded(); +} diff --git a/logic/java/JavaVersionList.h b/logic/java/JavaVersionList.h new file mode 100644 index 00000000..a46f33a2 --- /dev/null +++ b/logic/java/JavaVersionList.h @@ -0,0 +1,96 @@ +/* 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 +#include + +#include "logic/BaseVersionList.h" +#include "logic/tasks/Task.h" +#include "logic/java/JavaCheckerJob.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; +}; + +typedef std::shared_ptr 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 versions); + +protected: + QList m_vlist; + + bool m_loaded = false; +}; + +class JavaListLoadTask : public Task +{ + Q_OBJECT + +public: + explicit JavaListLoadTask(JavaVersionList *vlist); + ~JavaListLoadTask(); + + virtual void executeTask(); +public slots: + void javaCheckerFinished(QList results); + void checkerProgress(int current, int total); + +protected: + std::shared_ptr m_job; + JavaVersionList *m_list; + JavaVersion *m_currentRecommended; +}; -- cgit v1.2.3