From d38b90530b3ba3a49c4eb072eb344ae2b0836913 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= <peterix@gmail.com>
Date: Mon, 16 Sep 2013 00:54:39 +0200
Subject: Forge version list implementation. Needs integration and testing.

---
 logic/lists/BaseVersionList.cpp      | 123 +++++++++++++++++++++
 logic/lists/BaseVersionList.h        | 121 +++++++++++++++++++++
 logic/lists/ForgeVersionList.cpp     | 200 +++++++++++++++++++++++++++++++++++
 logic/lists/ForgeVersionList.h       |  98 +++++++++++++++++
 logic/lists/InstVersionList.cpp      | 129 ----------------------
 logic/lists/InstVersionList.h        | 121 ---------------------
 logic/lists/LwjglVersionList.cpp     |   8 --
 logic/lists/LwjglVersionList.h       |   2 -
 logic/lists/MinecraftVersionList.cpp |  34 ++----
 logic/lists/MinecraftVersionList.h   |  21 ++--
 10 files changed, 559 insertions(+), 298 deletions(-)
 create mode 100644 logic/lists/BaseVersionList.cpp
 create mode 100644 logic/lists/BaseVersionList.h
 create mode 100644 logic/lists/ForgeVersionList.cpp
 create mode 100644 logic/lists/ForgeVersionList.h
 delete mode 100644 logic/lists/InstVersionList.cpp
 delete mode 100644 logic/lists/InstVersionList.h

(limited to 'logic/lists')

diff --git a/logic/lists/BaseVersionList.cpp b/logic/lists/BaseVersionList.cpp
new file mode 100644
index 00000000..61da5eeb
--- /dev/null
+++ b/logic/lists/BaseVersionList.cpp
@@ -0,0 +1,123 @@
+/* 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 "logic/lists/BaseVersionList.h"
+#include "logic/BaseVersion.h"
+
+BaseVersionList::BaseVersionList(QObject *parent) :
+	QAbstractListModel(parent)
+{
+}
+
+BaseVersionPtr BaseVersionList::findVersion( const QString& descriptor )
+{
+	for (int i = 0; i < count(); i++)
+	{
+		if (at(i)->descriptor() == descriptor)
+			return at(i);
+	}
+	return BaseVersionPtr();
+}
+
+BaseVersionPtr BaseVersionList::getLatestStable() const
+{
+	if (count() <= 0)
+		return BaseVersionPtr();
+	else
+		return at(0);
+}
+
+QVariant BaseVersionList::data(const QModelIndex &index, int role) const
+{
+	if (!index.isValid())
+		return QVariant();
+	
+	if (index.row() > count())
+		return QVariant();
+	
+	
+	BaseVersionPtr version = at(index.row());
+	
+	switch (role)
+	{
+	case Qt::DisplayRole:
+		switch (index.column())
+		{
+		case NameColumn:
+			return version->name();
+			
+		case TypeColumn:
+			return version->typeString();
+			
+		default:
+			return QVariant();
+		}
+		
+	case Qt::ToolTipRole:
+		return version->descriptor();
+		
+	case VersionPointerRole:
+		return qVariantFromValue(version);
+		
+	default:
+		return QVariant();
+	}
+}
+
+QVariant BaseVersionList::headerData(int section, Qt::Orientation orientation, int role) const
+{
+	switch (role)
+	{
+	case Qt::DisplayRole:
+		switch (section)
+		{
+		case NameColumn:
+			return "Name";
+			
+		case TypeColumn:
+			return "Type";
+		
+		default:
+			return QVariant();
+		}
+		
+	case Qt::ToolTipRole:
+		switch (section)
+		{
+		case NameColumn:
+			return "The name of the version.";
+			
+		case TypeColumn:
+			return "The version's type.";
+		
+		default:
+			return QVariant();
+		}
+		
+	default:
+		return QVariant();
+	}
+}
+
+int BaseVersionList::rowCount(const QModelIndex &parent) const
+{
+	// Return count
+	return count();
+}
+
+int BaseVersionList::columnCount(const QModelIndex &parent) const
+{
+	return 2;
+}
diff --git a/logic/lists/BaseVersionList.h b/logic/lists/BaseVersionList.h
new file mode 100644
index 00000000..d37431ed
--- /dev/null
+++ b/logic/lists/BaseVersionList.h
@@ -0,0 +1,121 @@
+/* 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 <QVariant>
+#include <QAbstractListModel>
+#include <QSharedPointer>
+
+#include "logic/BaseVersion.h"
+
+class Task;
+
+/*!
+ * \brief Class that each instance type's version list derives from. 
+ * Version lists are the lists that keep track of the available game versions 
+ * for that instance. This list will not be loaded on startup. It will be loaded 
+ * when the list's load function is called. Before using the version list, you
+ * should check to see if it has been loaded yet and if not, load the list.
+ * 
+ * Note that this class also inherits from QAbstractListModel. Methods from that
+ * class determine how this version list shows up in a list view. Said methods
+ * all have a default implementation, but they can be overridden by plugins to
+ * change the behavior of the list.
+ */
+class BaseVersionList : public QAbstractListModel
+{
+	Q_OBJECT
+public:
+	enum ModelRoles
+	{
+		VersionPointerRole = 0x34B1CB48
+	};
+	
+	enum VListColumns
+	{
+		// First column - Name
+		NameColumn = 0,
+		
+		// Second column - Type
+		TypeColumn,
+		
+		// Third column - Timestamp
+		TimeColumn
+	};
+	
+	explicit BaseVersionList(QObject *parent = 0);
+	
+	/*!
+	 * \brief Gets a task that will reload the version list.
+	 * Simply execute the task to load the list.
+	 * The task returned by this function should reset the model when it's done.
+	 * \return A pointer to a task that reloads the version list.
+	 */
+	virtual Task *getLoadTask() = 0;
+	
+	//! Checks whether or not the list is loaded. If this returns false, the list should be loaded.
+	virtual bool isLoaded() = 0;
+	
+	//! Gets the version at the given index.
+	virtual const BaseVersionPtr at(int i) const = 0;
+	
+	//! Returns the number of versions in the list.
+	virtual int count() const = 0;
+	
+	
+	//////// List Model Functions ////////
+	virtual QVariant data(const QModelIndex &index, int role) const;
+	virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const;
+	virtual int rowCount(const QModelIndex &parent) const;
+	virtual int columnCount(const QModelIndex &parent) const;
+	
+	
+	/*!
+	 * \brief Finds a version by its descriptor.
+	 * \param The descriptor of the version to find.
+	 * \return A const pointer to the version with the given descriptor. NULL if
+	 * one doesn't exist.
+	 */
+	virtual BaseVersionPtr findVersion(const QString &descriptor);
+	
+	/*!
+	 * \brief Gets the latest stable version of this instance type.
+	 * This is the version that will be selected by default.
+	 * By default, this is simply the first version in the list.
+	 */
+	virtual BaseVersionPtr getLatestStable() const;
+	
+	/*!
+	 * Sorts the version list.
+	 */
+	virtual void sort() = 0;
+	
+protected slots:
+	/*!
+	 * Updates this list with the given list of versions.
+	 * This is done by copying each version in the given list and inserting it
+	 * into this one.
+	 * We need to do this so that we can set the parents of the versions are set to this
+	 * version list. This can't be done in the load task, because the versions the load
+	 * task creates are on the load task's thread and Qt won't allow their parents
+	 * to be set to something created on another thread.
+	 * To get around that problem, we invoke this method on the GUI thread, which
+	 * then copies the versions and sets their parents correctly.
+	 * \param versions List of versions whose parents should be set.
+	 */
+	virtual void updateListData(QList<BaseVersionPtr > versions) = 0;
+};
diff --git a/logic/lists/ForgeVersionList.cpp b/logic/lists/ForgeVersionList.cpp
new file mode 100644
index 00000000..f45b8b6b
--- /dev/null
+++ b/logic/lists/ForgeVersionList.cpp
@@ -0,0 +1,200 @@
+/* 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 "ForgeVersionList.h"
+#include <logic/net/DownloadJob.h>
+#include "MultiMC.h"
+
+#include <QtNetwork>
+
+#include <QtXml>
+
+#include <QRegExp>
+
+#define JSON_URL "http://files.minecraftforge.net/minecraftforge/json"
+
+
+ForgeVersionList::ForgeVersionList(QObject* parent): BaseVersionList(parent)
+{
+	
+}
+
+Task *ForgeVersionList::getLoadTask()
+{
+	return new ForgeListLoadTask(this);
+}
+
+bool ForgeVersionList::isLoaded()
+{
+	return m_loaded;
+}
+
+const BaseVersionPtr ForgeVersionList::at(int i) const
+{
+	return m_vlist.at(i);
+}
+
+int ForgeVersionList::count() const
+{
+	return m_vlist.count();
+}
+/*
+bool cmpVersions(BaseVersionPtr first, BaseVersionPtr second)
+{
+	const BaseVersion & left = *first;
+	const BaseVersion & right = *second;
+	return left > right;
+}
+
+void MinecraftVersionList::sort()
+{
+	beginResetModel();
+	qSort(m_vlist.begin(), m_vlist.end(), cmpVersions);
+	endResetModel();
+}
+*/
+BaseVersionPtr ForgeVersionList::getLatestStable() const
+{
+	return BaseVersionPtr();
+}
+
+void ForgeVersionList::updateListData(QList<BaseVersionPtr > versions)
+{
+	beginResetModel();
+	m_vlist = versions;
+	m_loaded = true;
+	endResetModel();
+	// NOW SORT!!
+	// sort();
+}
+
+void ForgeVersionList::sort()
+{
+	// NO-OP for now
+}
+
+
+ForgeListLoadTask::ForgeListLoadTask(ForgeVersionList* vlist): Task()
+{
+	m_list = vlist;
+}
+
+
+void ForgeListLoadTask::executeTask()
+{
+	auto job = new DownloadJob("Version index");
+	job->add(QUrl(JSON_URL));
+	listJob.reset(job);
+	connect(listJob.data(), SIGNAL(succeeded()), SLOT(list_downloaded()));
+	connect(listJob.data(), SIGNAL(failed()), SLOT(versionFileFailed()));
+	connect(listJob.data(), SIGNAL(progress(qint64,qint64)), SLOT(updateDownloadProgress(qint64,qint64)));
+	listJob->start();
+}
+
+void ForgeListLoadTask::list_downloaded()
+{
+	auto DlJob = listJob->first();
+	auto data = DlJob.dynamicCast<ByteArrayDownload>()->m_data;
+	
+	
+	QJsonParseError jsonError;
+	QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &jsonError);
+	DlJob.reset();
+	
+	if (jsonError.error != QJsonParseError::NoError)
+	{
+		emitFailed("Error parsing version list JSON:" + jsonError.errorString());
+		return;
+	}
+
+	if(!jsonDoc.isObject())
+	{
+		emitFailed("Error parsing version list JSON: jsonDoc is not an object");
+		return;
+	}
+	
+	QJsonObject root = jsonDoc.object();
+	
+	// Now, get the array of versions.
+	if(!root.value("builds").isArray())
+	{
+		emitFailed("Error parsing version list JSON: version list object is missing 'builds' array");
+		return;
+	}
+	QJsonArray builds = root.value("builds").toArray();
+	
+	QList<BaseVersionPtr > tempList;
+	for (int i = 0; i < builds.count(); i++)
+	{
+		// Load the version info.
+		if(!builds[i].isObject())
+		{
+			//FIXME: log this somewhere
+			continue;
+		}
+		QJsonObject obj = builds[i].toObject();
+		int build_nr = obj.value("build").toDouble(0);
+		if(!build_nr)
+			continue;
+		QJsonArray files = root.value("files").toArray();
+		QString url, jobbuildver, mcver, buildtype, filename;
+		QString changelog_url, installer_url;
+		bool valid = false;
+		for(int j = 0; j < files.count(); j++)
+		{
+			if(!files[j].isObject())
+				continue;
+			QJsonObject file = files[j].toObject();
+			buildtype = file.value("buildtype").toString();
+			if((buildtype == "client" || buildtype == "universal") && !valid)
+			{
+				mcver = file.value("mcver").toString();
+				url = file.value("url").toString();
+				jobbuildver = file.value("jobbuildver").toString();
+				int lastSlash = url.lastIndexOf('/');
+				filename = url.mid(lastSlash+1);
+				valid = true;
+			}
+			else if(buildtype == "changelog")
+			{
+				QString ext = file.value("ext").toString();
+				if(ext.isEmpty())
+					continue;
+				changelog_url = file.value("url").toString();
+			}
+			else if(buildtype == "installer")
+			{
+				installer_url = file.value("url").toString();
+			}
+		}
+		if(valid)
+		{
+			// Now, we construct the version object and add it to the list.
+			QSharedPointer<ForgeVersion> fVersion(new ForgeVersion());
+			fVersion->universal_url = url;
+			fVersion->changelog_url = changelog_url;
+			fVersion->installer_url = installer_url;
+			fVersion->jobbuildver = jobbuildver;
+			fVersion->mcver = mcver;
+			fVersion->filename = filename;
+			fVersion->m_buildnr = build_nr;
+			tempList.append(fVersion);
+		}
+	}
+	m_list->updateListData(tempList);
+	
+	emitSucceeded();
+	return;
+}
diff --git a/logic/lists/ForgeVersionList.h b/logic/lists/ForgeVersionList.h
new file mode 100644
index 00000000..8d4a2d46
--- /dev/null
+++ b/logic/lists/ForgeVersionList.h
@@ -0,0 +1,98 @@
+/* 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 <QUrl>
+
+#include <QNetworkReply>
+#include "BaseVersionList.h"
+#include "logic/tasks/Task.h"
+#include "logic/net/DownloadJob.h"
+
+class ForgeVersion;
+typedef QSharedPointer<ForgeVersion> PtrForgeVersion;
+
+struct ForgeVersion : public BaseVersion
+{
+	virtual QString descriptor()
+	{
+		return filename;
+	};
+	virtual QString name()
+	{
+		return "Forge " + jobbuildver + " (" + mcver + ")";
+	};
+	virtual QString typeString() const
+	{
+		if(installer_url.isEmpty())
+			return "Universal";
+		else
+			return "Installer";
+	};
+	
+	int m_buildnr = 0;
+	QString universal_url;
+	QString changelog_url;
+	QString installer_url;
+	QString jobbuildver;
+	QString mcver;
+	QString filename;
+};
+
+class ForgeVersionList : public BaseVersionList
+{
+	Q_OBJECT
+public:
+	friend class ForgeListLoadTask;
+	
+	explicit ForgeVersionList(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 getLatestStable() const;
+	
+protected:
+	QList<BaseVersionPtr > m_vlist;
+	
+	bool m_loaded;
+	
+protected slots:
+	virtual void updateListData(QList<BaseVersionPtr > versions);
+};
+
+class ForgeListLoadTask : public Task
+{
+	Q_OBJECT
+	
+public:
+	explicit ForgeListLoadTask(ForgeVersionList *vlist);
+	
+	virtual void executeTask();
+	
+protected slots:
+	void list_downloaded();
+	
+protected:
+	DownloadJobPtr listJob;
+	ForgeVersionList *m_list;
+};
diff --git a/logic/lists/InstVersionList.cpp b/logic/lists/InstVersionList.cpp
deleted file mode 100644
index 7dc67155..00000000
--- a/logic/lists/InstVersionList.cpp
+++ /dev/null
@@ -1,129 +0,0 @@
-/* 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 "logic/lists/InstVersionList.h"
-#include "logic/InstanceVersion.h"
-
-InstVersionList::InstVersionList(QObject *parent) :
-	QAbstractListModel(parent)
-{
-}
-
-InstVersionPtr InstVersionList::findVersion( const QString& descriptor )
-{
-	for (int i = 0; i < count(); i++)
-	{
-		if (at(i)->descriptor == descriptor)
-			return at(i);
-	}
-	return InstVersionPtr();
-}
-
-InstVersionPtr InstVersionList::getLatestStable() const
-{
-	if (count() <= 0)
-		return InstVersionPtr();
-	else
-		return at(0);
-}
-
-QVariant InstVersionList::data(const QModelIndex &index, int role) const
-{
-	if (!index.isValid())
-		return QVariant();
-	
-	if (index.row() > count())
-		return QVariant();
-	
-	
-	InstVersionPtr version = at(index.row());
-	
-	switch (role)
-	{
-	case Qt::DisplayRole:
-		switch (index.column())
-		{
-		case NameColumn:
-			return version->name;
-			
-		case TypeColumn:
-			return version->typeString();
-			
-		case TimeColumn:
-			return version->timestamp;
-			
-		default:
-			return QVariant();
-		}
-		
-	case Qt::ToolTipRole:
-		return version->descriptor;
-		
-	case VersionPointerRole:
-		return qVariantFromValue(version);
-		
-	default:
-		return QVariant();
-	}
-}
-
-QVariant InstVersionList::headerData(int section, Qt::Orientation orientation, int role) const
-{
-	switch (role)
-	{
-	case Qt::DisplayRole:
-		switch (section)
-		{
-		case NameColumn:
-			return "Name";
-			
-		case TypeColumn:
-			return "Type";
-			
-		case TimeColumn:
-			return "Time";
-		
-		default:
-			return QVariant();
-		}
-		
-	case Qt::ToolTipRole:
-		switch (section)
-		{
-		case NameColumn:
-			return "The name of the version.";
-			
-		case TypeColumn:
-			return "The version's type.";
-		
-		default:
-			return QVariant();
-		}
-		
-	default:
-		return QVariant();
-	}
-}
-
-int InstVersionList::rowCount(const QModelIndex &parent) const
-{
-	// Return count
-	return count();
-}
-
-int InstVersionList::columnCount(const QModelIndex &parent) const
-{
-	return 2;
-}
diff --git a/logic/lists/InstVersionList.h b/logic/lists/InstVersionList.h
deleted file mode 100644
index bc6aa5d4..00000000
--- a/logic/lists/InstVersionList.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/* 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 <QVariant>
-#include <QAbstractListModel>
-#include <QSharedPointer>
-
-#include "logic/InstanceVersion.h"
-
-class Task;
-
-/*!
- * \brief Class that each instance type's version list derives from. 
- * Version lists are the lists that keep track of the available game versions 
- * for that instance. This list will not be loaded on startup. It will be loaded 
- * when the list's load function is called. Before using the version list, you
- * should check to see if it has been loaded yet and if not, load the list.
- * 
- * Note that this class also inherits from QAbstractListModel. Methods from that
- * class determine how this version list shows up in a list view. Said methods
- * all have a default implementation, but they can be overridden by plugins to
- * change the behavior of the list.
- */
-class InstVersionList : public QAbstractListModel
-{
-	Q_OBJECT
-public:
-	enum ModelRoles
-	{
-		VersionPointerRole = 0x34B1CB48
-	};
-	
-	enum VListColumns
-	{
-		// First column - Name
-		NameColumn = 0,
-		
-		// Second column - Type
-		TypeColumn,
-		
-		// Third column - Timestamp
-		TimeColumn
-	};
-	
-	explicit InstVersionList(QObject *parent = 0);
-	
-	/*!
-	 * \brief Gets a task that will reload the version list.
-	 * Simply execute the task to load the list.
-	 * The task returned by this function should reset the model when it's done.
-	 * \return A pointer to a task that reloads the version list.
-	 */
-	virtual Task *getLoadTask() = 0;
-	
-	//! Checks whether or not the list is loaded. If this returns false, the list should be loaded.
-	virtual bool isLoaded() = 0;
-	
-	//! Gets the version at the given index.
-	virtual const InstVersionPtr at(int i) const = 0;
-	
-	//! Returns the number of versions in the list.
-	virtual int count() const = 0;
-	
-	
-	//////// List Model Functions ////////
-	virtual QVariant data(const QModelIndex &index, int role) const;
-	virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const;
-	virtual int rowCount(const QModelIndex &parent) const;
-	virtual int columnCount(const QModelIndex &parent) const;
-	
-	
-	/*!
-	 * \brief Finds a version by its descriptor.
-	 * \param The descriptor of the version to find.
-	 * \return A const pointer to the version with the given descriptor. NULL if
-	 * one doesn't exist.
-	 */
-	virtual InstVersionPtr findVersion(const QString &descriptor);
-	
-	/*!
-	 * \brief Gets the latest stable version of this instance type.
-	 * This is the version that will be selected by default.
-	 * By default, this is simply the first version in the list.
-	 */
-	virtual InstVersionPtr getLatestStable() const;
-	
-	/*!
-	 * Sorts the version list.
-	 */
-	virtual void sort() = 0;
-	
-protected slots:
-	/*!
-	 * Updates this list with the given list of versions.
-	 * This is done by copying each version in the given list and inserting it
-	 * into this one.
-	 * We need to do this so that we can set the parents of the versions are set to this
-	 * version list. This can't be done in the load task, because the versions the load
-	 * task creates are on the load task's thread and Qt won't allow their parents
-	 * to be set to something created on another thread.
-	 * To get around that problem, we invoke this method on the GUI thread, which
-	 * then copies the versions and sets their parents correctly.
-	 * \param versions List of versions whose parents should be set.
-	 */
-	virtual void updateListData(QList<InstVersionPtr > versions) = 0;
-};
diff --git a/logic/lists/LwjglVersionList.cpp b/logic/lists/LwjglVersionList.cpp
index d7826a82..b3e2dab4 100644
--- a/logic/lists/LwjglVersionList.cpp
+++ b/logic/lists/LwjglVersionList.cpp
@@ -24,14 +24,6 @@
 
 #define RSS_URL "http://sourceforge.net/api/file/index/project-id/58488/mtime/desc/rss"
 
-LWJGLVersionList mainVersionList;
-
-LWJGLVersionList &LWJGLVersionList::get()
-{
-	return mainVersionList;
-}
-
-
 LWJGLVersionList::LWJGLVersionList(QObject *parent) :
 	QAbstractListModel(parent)
 {
diff --git a/logic/lists/LwjglVersionList.h b/logic/lists/LwjglVersionList.h
index 638a0b67..23e92a1a 100644
--- a/logic/lists/LwjglVersionList.h
+++ b/logic/lists/LwjglVersionList.h
@@ -53,8 +53,6 @@ class LWJGLVersionList : public QAbstractListModel
 public:
 	explicit LWJGLVersionList(QObject *parent = 0);
 	
-	static LWJGLVersionList &get();
-	
 	bool isLoaded() { return m_vlist.length() > 0; }
 	
 	const PtrLWJGLVersion getVersion(const QString &versionName);
diff --git a/logic/lists/MinecraftVersionList.cpp b/logic/lists/MinecraftVersionList.cpp
index 42fb1b50..86ba0792 100644
--- a/logic/lists/MinecraftVersionList.cpp
+++ b/logic/lists/MinecraftVersionList.cpp
@@ -34,10 +34,8 @@
 #define ASSETS_URLBASE "http://assets.minecraft.net/"
 #define MCN_URLBASE "http://sonicrules.org/mcnweb.py"
 
-MinecraftVersionList mcVList;
-
 MinecraftVersionList::MinecraftVersionList(QObject *parent) :
-	InstVersionList(parent)
+	BaseVersionList(parent)
 {
 	
 }
@@ -52,7 +50,7 @@ bool MinecraftVersionList::isLoaded()
 	return m_loaded;
 }
 
-const InstVersionPtr MinecraftVersionList::at(int i) const
+const BaseVersionPtr MinecraftVersionList::at(int i) const
 {
 	return m_vlist.at(i);
 }
@@ -62,11 +60,11 @@ int MinecraftVersionList::count() const
 	return m_vlist.count();
 }
 
-bool cmpVersions(InstVersionPtr first, InstVersionPtr second)
+bool cmpVersions(BaseVersionPtr first, BaseVersionPtr second)
 {
-	const InstVersion & left = *first;
-	const InstVersion & right = *second;
-	return left > right;
+	auto left = first.dynamicCast<MinecraftVersion>();
+	auto right = second.dynamicCast<MinecraftVersion>();
+	return left->timestamp > right->timestamp;
 }
 
 void MinecraftVersionList::sort()
@@ -76,7 +74,7 @@ void MinecraftVersionList::sort()
 	endResetModel();
 }
 
-InstVersionPtr MinecraftVersionList::getLatestStable() const
+BaseVersionPtr MinecraftVersionList::getLatestStable() const
 {
 	for (int i = 0; i < m_vlist.length(); i++)
 	{
@@ -86,15 +84,10 @@ InstVersionPtr MinecraftVersionList::getLatestStable() const
 			return m_vlist.at(i);
 		}
 	}
-	return InstVersionPtr();
-}
-
-MinecraftVersionList &MinecraftVersionList::getMainList()
-{
-	return mcVList;
+	return BaseVersionPtr();
 }
 
-void MinecraftVersionList::updateListData(QList<InstVersionPtr > versions)
+void MinecraftVersionList::updateListData(QList<BaseVersionPtr > versions)
 {
 	beginResetModel();
 	m_vlist = versions;
@@ -214,7 +207,7 @@ void MCVListLoadTask::list_downloaded()
 	}
 	QJsonArray versions = root.value("versions").toArray();
 	
-	QList<InstVersionPtr > tempList;
+	QList<BaseVersionPtr > tempList;
 	for (int i = 0; i < versions.count(); i++)
 	{
 		bool is_snapshot = false;
@@ -280,7 +273,7 @@ void MCVListLoadTask::list_downloaded()
 		
 		// Now, we construct the version object and add it to the list.
 		QSharedPointer<MinecraftVersion> mcVersion(new MinecraftVersion());
-		mcVersion->name = mcVersion->descriptor = versionID;
+		mcVersion->m_name = mcVersion->m_descriptor = versionID;
 		mcVersion->timestamp = versionTime.toMSecsSinceEpoch();
 		mcVersion->download_url = dlUrl;
 		mcVersion->is_latest = is_latest;
@@ -293,8 +286,3 @@ void MCVListLoadTask::list_downloaded()
 	emitSucceeded();
 	return;
 }
-
-// FIXME: we should have a local cache of the version list and a local cache of version data
-bool MCVListLoadTask::loadFromVList()
-{
-}
diff --git a/logic/lists/MinecraftVersionList.h b/logic/lists/MinecraftVersionList.h
index 0477379f..8937ba7b 100644
--- a/logic/lists/MinecraftVersionList.h
+++ b/logic/lists/MinecraftVersionList.h
@@ -20,14 +20,14 @@
 #include <QSet>
 #include <QSharedPointer>
 
-#include "InstVersionList.h"
+#include "BaseVersionList.h"
 #include "logic/tasks/Task.h"
 #include "logic/MinecraftVersion.h"
 
 class MCVListLoadTask;
 class QNetworkReply;
 
-class MinecraftVersionList : public InstVersionList
+class MinecraftVersionList : public BaseVersionList
 {
 	Q_OBJECT
 public:
@@ -37,25 +37,19 @@ public:
 	
 	virtual Task *getLoadTask();
 	virtual bool isLoaded();
-	virtual const InstVersionPtr at(int i) const;
+	virtual const BaseVersionPtr at(int i) const;
 	virtual int count() const;
 	virtual void sort();
 	
-	virtual InstVersionPtr getLatestStable() const;
-	
-	/*!
-	 * Gets the main version list instance.
-	 */
-	static MinecraftVersionList &getMainList();
-	
+	virtual BaseVersionPtr getLatestStable() const;
 	
 protected:
-	QList<InstVersionPtr > m_vlist;
+	QList<BaseVersionPtr> m_vlist;
 	
 	bool m_loaded;
 	
 protected slots:
-	virtual void updateListData(QList<InstVersionPtr > versions);
+	virtual void updateListData(QList<BaseVersionPtr > versions);
 };
 
 class MCVListLoadTask : public Task
@@ -72,9 +66,6 @@ protected slots:
 	void list_downloaded();
 	
 protected:
-	//! Loads versions from Mojang's official version list.
-	bool loadFromVList();
-	
 	QNetworkReply *vlistReply;
 	MinecraftVersionList *m_list;
 	MinecraftVersion *m_currentStable;
-- 
cgit v1.2.3


From b979d0ce5da515793a02802a6421ef607a498323 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= <peterix@gmail.com>
Date: Wed, 18 Sep 2013 00:00:35 +0200
Subject: Implement legacy forge button!

Many refactors of the task system.
Progress dialog now accepts generic ProgressProvider objects
---
 logic/lists/ForgeVersionList.cpp   | 93 +++++++++++++++++++++++++++++++++-----
 logic/lists/ForgeVersionList.h     | 10 ++--
 logic/lists/MinecraftVersionList.h |  2 +-
 3 files changed, 89 insertions(+), 16 deletions(-)

(limited to 'logic/lists')

diff --git a/logic/lists/ForgeVersionList.cpp b/logic/lists/ForgeVersionList.cpp
index f45b8b6b..412c04fe 100644
--- a/logic/lists/ForgeVersionList.cpp
+++ b/logic/lists/ForgeVersionList.cpp
@@ -50,21 +50,90 @@ int ForgeVersionList::count() const
 {
 	return m_vlist.count();
 }
-/*
-bool cmpVersions(BaseVersionPtr first, BaseVersionPtr second)
+
+int ForgeVersionList::columnCount(const QModelIndex& parent) const
 {
-	const BaseVersion & left = *first;
-	const BaseVersion & right = *second;
-	return left > right;
+    return 3;
 }
 
-void MinecraftVersionList::sort()
+QVariant ForgeVersionList::data(const QModelIndex &index, int role) const
 {
-	beginResetModel();
-	qSort(m_vlist.begin(), m_vlist.end(), cmpVersions);
-	endResetModel();
+	if (!index.isValid())
+		return QVariant();
+	
+	if (index.row() > count())
+		return QVariant();
+	
+	auto version = m_vlist[index.row()].dynamicCast<ForgeVersion>();
+	switch (role)
+	{
+	case Qt::DisplayRole:
+		switch (index.column())
+		{
+		case 0:
+			return version->name();
+			
+		case 1:
+			return version->mcver;
+			
+		case 2:
+			return version->typeString();
+		default:
+			return QVariant();
+		}
+		
+	case Qt::ToolTipRole:
+		return version->descriptor();
+		
+	case VersionPointerRole:
+		return qVariantFromValue(m_vlist[index.row()]);
+		
+	default:
+		return QVariant();
+	}
 }
-*/
+
+QVariant ForgeVersionList::headerData(int section, Qt::Orientation orientation, int role) const
+{
+	switch (role)
+	{
+	case Qt::DisplayRole:
+		switch (section)
+		{
+		case 0:
+			return "Version";
+			
+		case 1:
+			return "Minecraft";
+			
+		case 2:
+			return "Type";
+		
+		default:
+			return QVariant();
+		}
+		
+	case Qt::ToolTipRole:
+		switch (section)
+		{
+		case 0:
+			return "The name of the version.";
+			
+		case 1:
+			return "Minecraft version";
+			
+		case 2:
+			return "The version's type.";
+		
+		default:
+			return QVariant();
+		}
+		
+	default:
+		return QVariant();
+	}
+}
+
 BaseVersionPtr ForgeVersionList::getLatestStable() const
 {
 	return BaseVersionPtr();
@@ -99,7 +168,7 @@ void ForgeListLoadTask::executeTask()
 	listJob.reset(job);
 	connect(listJob.data(), SIGNAL(succeeded()), SLOT(list_downloaded()));
 	connect(listJob.data(), SIGNAL(failed()), SLOT(versionFileFailed()));
-	connect(listJob.data(), SIGNAL(progress(qint64,qint64)), SLOT(updateDownloadProgress(qint64,qint64)));
+	connect(listJob.data(), SIGNAL(progress(qint64,qint64)), SIGNAL(progress(qint64,qint64)));
 	listJob->start();
 }
 
@@ -148,7 +217,7 @@ void ForgeListLoadTask::list_downloaded()
 		int build_nr = obj.value("build").toDouble(0);
 		if(!build_nr)
 			continue;
-		QJsonArray files = root.value("files").toArray();
+		QJsonArray files = obj.value("files").toArray();
 		QString url, jobbuildver, mcver, buildtype, filename;
 		QString changelog_url, installer_url;
 		bool valid = false;
diff --git a/logic/lists/ForgeVersionList.h b/logic/lists/ForgeVersionList.h
index 8d4a2d46..ca6b27bc 100644
--- a/logic/lists/ForgeVersionList.h
+++ b/logic/lists/ForgeVersionList.h
@@ -26,7 +26,7 @@
 #include "logic/net/DownloadJob.h"
 
 class ForgeVersion;
-typedef QSharedPointer<ForgeVersion> PtrForgeVersion;
+typedef QSharedPointer<ForgeVersion> ForgeVersionPtr;
 
 struct ForgeVersion : public BaseVersion
 {
@@ -36,7 +36,7 @@ struct ForgeVersion : public BaseVersion
 	};
 	virtual QString name()
 	{
-		return "Forge " + jobbuildver + " (" + mcver + ")";
+		return "Forge " + jobbuildver;
 	};
 	virtual QString typeString() const
 	{
@@ -71,8 +71,12 @@ public:
 	
 	virtual BaseVersionPtr getLatestStable() 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;
+	
 protected:
-	QList<BaseVersionPtr > m_vlist;
+	QList<BaseVersionPtr> m_vlist;
 	
 	bool m_loaded;
 	
diff --git a/logic/lists/MinecraftVersionList.h b/logic/lists/MinecraftVersionList.h
index 8937ba7b..fb28ddfe 100644
--- a/logic/lists/MinecraftVersionList.h
+++ b/logic/lists/MinecraftVersionList.h
@@ -49,7 +49,7 @@ protected:
 	bool m_loaded;
 	
 protected slots:
-	virtual void updateListData(QList<BaseVersionPtr > versions);
+	virtual void updateListData(QList<BaseVersionPtr> versions);
 };
 
 class MCVListLoadTask : public Task
-- 
cgit v1.2.3