Reorganize logic code.

This commit is contained in:
Petr Mrázek
2014-05-08 21:20:10 +02:00
parent 69a9ca39ad
commit 8a3a0f5a52
58 changed files with 188 additions and 189 deletions

124
logic/java/JavaChecker.cpp Normal file
View File

@ -0,0 +1,124 @@
#include "JavaChecker.h"
#include "MultiMC.h"
#include <pathutils.h>
#include <QFile>
#include <QProcess>
#include <QMap>
#include <QTemporaryFile>
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<QString, QString> 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();
}
}

42
logic/java/JavaChecker.h Normal file
View File

@ -0,0 +1,42 @@
#pragma once
#include <QProcess>
#include <QTimer>
#include <memory>
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<QProcess> QProcessPtr;
typedef std::shared_ptr<JavaChecker> 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);
};

View File

@ -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();
}
}

100
logic/java/JavaCheckerJob.h Normal file
View File

@ -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 <QtNetwork>
#include <QLabel>
#include "JavaChecker.h"
#include "logic/tasks/ProgressProvider.h"
class JavaCheckerJob;
typedef std::shared_ptr<JavaCheckerJob> 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 &current, 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<JavaCheckResult>);
public
slots:
virtual void start();
// FIXME: implement
virtual void abort() {};
private
slots:
void partFinished(JavaCheckResult result);
private:
QString m_job_name;
QList<JavaCheckerPtr> javacheckers;
QList<JavaCheckResult> javaresults;
qint64 current_progress = 0;
qint64 total_progress = 0;
int num_finished = 0;
bool m_running = false;
};

221
logic/java/JavaUtils.cpp Normal file
View File

@ -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 <QStringList>
#include <QString>
#include <QDir>
#include <QStringList>
#include <setting.h>
#include <pathutils.h>
#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<JavaVersionPtr> JavaUtils::FindJavaFromRegistryKey(DWORD keyType, QString keyName)
{
QList<JavaVersionPtr> 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<QString> JavaUtils::FindJavaPaths()
{
QList<JavaVersionPtr> java_candidates;
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");
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<QString> candidates;
for(JavaVersionPtr java_candidate : java_candidates)
{
if(!candidates.contains(java_candidate->path))
{
candidates.append(java_candidate->path);
}
}
return candidates;
}
#elif OSX
QList<QString> JavaUtils::FindJavaPaths()
{
QList<QString> 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<QString> JavaUtils::FindJavaPaths()
{
QLOG_INFO() << "Linux Java detection incomplete - defaulting to \"java\"";
QList<QString> javas;
javas.append(this->GetDefaultJava()->path);
javas.append("/opt/java/bin/java");
javas.append("/usr/bin/java");
return javas;
}
#else
QList<QString> JavaUtils::FindJavaPaths()
{
QLOG_INFO() << "Unknown operating system build - defaulting to \"java\"";
QList<QString> javas;
javas.append(this->GetDefaultJava()->path);
return javas;
}
#endif

43
logic/java/JavaUtils.h Normal file
View File

@ -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 <QStringList>
#include <QWidget>
#include <osutils.h>
#include "JavaCheckerJob.h"
#include "JavaChecker.h"
#include "JavaVersionList.h"
#if WINDOWS
#include <windows.h>
#endif
class JavaUtils : public QObject
{
Q_OBJECT
public:
JavaUtils();
JavaVersionPtr MakeJavaPtr(QString path, QString id = "unknown", QString arch = "unknown");
QList<QString> FindJavaPaths();
JavaVersionPtr GetDefaultJava();
#if WINDOWS
QList<JavaVersionPtr> FindJavaFromRegistryKey(DWORD keyType, QString keyName);
#endif
};

View File

@ -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 <QtNetwork>
#include <QtXml>
#include <QRegExp>
#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<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;
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<BaseVersionPtr> 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<QString> candidate_paths = ju.FindJavaPaths();
m_job = std::shared_ptr<JavaCheckerJob>(new JavaCheckerJob("Java detection"));
connect(m_job.get(), SIGNAL(finished(QList<JavaCheckResult>)), this, SLOT(javaCheckerFinished(QList<JavaCheckResult>)));
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<JavaCheckResult> results)
{
QList<JavaVersionPtr> 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<BaseVersionPtr> javas_bvp;
for (auto java : candidates)
{
//QLOG_INFO() << java->id << java->arch << " at " << java->path;
BaseVersionPtr bp_java = std::dynamic_pointer_cast<BaseVersion>(java);
if (bp_java)
{
javas_bvp.append(java);
}
}
m_list->updateListData(javas_bvp);
emitSucceeded();
}

View File

@ -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 <QObject>
#include <QAbstractListModel>
#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<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();
public slots:
void javaCheckerFinished(QList<JavaCheckResult> results);
void checkerProgress(int current, int total);
protected:
std::shared_ptr<JavaCheckerJob> m_job;
JavaVersionList *m_list;
JavaVersion *m_currentRecommended;
};