summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt3
-rw-r--r--gui/lwjglselectdialog.cpp68
-rw-r--r--gui/lwjglselectdialog.h46
-rw-r--r--gui/lwjglselectdialog.ui85
-rw-r--r--gui/mainwindow.cpp21
-rw-r--r--gui/mainwindow.h2
-rw-r--r--libmultimc/CMakeLists.txt2
-rw-r--r--libmultimc/include/lwjglversionlist.h128
-rw-r--r--libmultimc/src/lwjglversionlist.cpp204
9 files changed, 559 insertions, 0 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 523d55c9..10308e18 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -173,6 +173,7 @@ gui/consolewindow.h
gui/instancemodel.h
gui/instancedelegate.h
gui/versionselectdialog.h
+gui/lwjglselectdialog.h
gui/iconcache.h
multimc_pragma.h
@@ -203,6 +204,7 @@ gui/consolewindow.cpp
gui/instancemodel.cpp
gui/instancedelegate.cpp
gui/versionselectdialog.cpp
+gui/lwjglselectdialog.cpp
gui/iconcache.cpp
java/javautils.cpp
@@ -222,6 +224,7 @@ gui/browserdialog.ui
gui/aboutdialog.ui
gui/consolewindow.ui
gui/versionselectdialog.ui
+gui/lwjglselectdialog.ui
)
diff --git a/gui/lwjglselectdialog.cpp b/gui/lwjglselectdialog.cpp
new file mode 100644
index 00000000..ded299cf
--- /dev/null
+++ b/gui/lwjglselectdialog.cpp
@@ -0,0 +1,68 @@
+/* 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 "lwjglselectdialog.h"
+#include "ui_lwjglselectdialog.h"
+
+#include "lwjglversionlist.h"
+
+LWJGLSelectDialog::LWJGLSelectDialog(QWidget *parent) :
+ QDialog(parent),
+ ui(new Ui::LWJGLSelectDialog)
+{
+ ui->setupUi(this);
+ ui->labelStatus->setVisible(false);
+ ui->lwjglListView->setModel(&LWJGLVersionList::get());
+
+ connect(&LWJGLVersionList::get(), SIGNAL(loadingStateUpdated(bool)), SLOT(loadingStateUpdated(bool)));
+ connect(&LWJGLVersionList::get(), SIGNAL(loadListFailed(QString)), SLOT(loadingFailed(QString)));
+ loadingStateUpdated(LWJGLVersionList::get().isLoading());
+}
+
+LWJGLSelectDialog::~LWJGLSelectDialog()
+{
+ delete ui;
+}
+
+QString LWJGLSelectDialog::selectedVersion() const
+{
+ return LWJGLVersionList::get().data(
+ ui->lwjglListView->selectionModel()->currentIndex(),
+ Qt::DisplayRole).toString();
+}
+
+void LWJGLSelectDialog::on_refreshButton_clicked()
+{
+ if (!LWJGLVersionList::get().isLoading())
+ LWJGLVersionList::get().loadList();
+}
+
+void LWJGLSelectDialog::loadingStateUpdated(bool loading)
+{
+ setEnabled(!loading);
+ if (loading)
+ {
+ ui->labelStatus->setText("Loading LWJGL version list...");
+ ui->labelStatus->setStyleSheet("QLabel { color: black; }");
+ }
+ ui->labelStatus->setVisible(loading);
+}
+
+void LWJGLSelectDialog::loadingFailed(QString error)
+{
+ ui->labelStatus->setText(error);
+ ui->labelStatus->setStyleSheet("QLabel { color: red; }");
+ ui->labelStatus->setVisible(true);
+}
diff --git a/gui/lwjglselectdialog.h b/gui/lwjglselectdialog.h
new file mode 100644
index 00000000..1772904a
--- /dev/null
+++ b/gui/lwjglselectdialog.h
@@ -0,0 +1,46 @@
+/* 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.
+ */
+
+#ifndef LWJGLSELECTDIALOG_H
+#define LWJGLSELECTDIALOG_H
+
+#include <QDialog>
+
+namespace Ui
+{
+class LWJGLSelectDialog;
+}
+
+class LWJGLSelectDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit LWJGLSelectDialog(QWidget *parent = 0);
+ ~LWJGLSelectDialog();
+
+ QString selectedVersion() const;
+
+private slots:
+ void on_refreshButton_clicked();
+
+ void loadingStateUpdated(bool loading);
+ void loadingFailed(QString error);
+
+private:
+ Ui::LWJGLSelectDialog *ui;
+};
+
+#endif // LWJGLSELECTDIALOG_H
diff --git a/gui/lwjglselectdialog.ui b/gui/lwjglselectdialog.ui
new file mode 100644
index 00000000..c715cc07
--- /dev/null
+++ b/gui/lwjglselectdialog.ui
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>LWJGLSelectDialog</class>
+ <widget class="QDialog" name="LWJGLSelectDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Dialog</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QLabel" name="labelStatus">
+ <property name="text">
+ <string>Status label...</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QListView" name="lwjglListView"/>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QPushButton" name="refreshButton">
+ <property name="text">
+ <string>&amp;Refresh</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>LWJGLSelectDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>LWJGLSelectDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp
index 47753b37..e60155c6 100644
--- a/gui/mainwindow.cpp
+++ b/gui/mainwindow.cpp
@@ -40,6 +40,7 @@
#include "gui/browserdialog.h"
#include "gui/aboutdialog.h"
#include "gui/versionselectdialog.h"
+#include "gui/lwjglselectdialog.h"
#include "gui/consolewindow.h"
#include "kcategorizedview.h"
@@ -59,6 +60,7 @@
#include "instancedelegate.h"
#include "minecraftversionlist.h"
+#include "lwjglversionlist.h"
// Opens the given file in the default application.
// TODO: Move this somewhere.
@@ -140,6 +142,11 @@ MainWindow::MainWindow ( QWidget *parent ) :
m_versionLoadTask = MinecraftVersionList::getMainList().getLoadTask();
startTask(m_versionLoadTask);
}
+
+ if (!LWJGLVersionList::get().isLoaded())
+ {
+ LWJGLVersionList::get().loadList();
+ }
}
MainWindow::~MainWindow()
@@ -460,3 +467,17 @@ void MainWindow::on_actionChangeInstMCVersion_triggered()
inst->setIntendedVersion(vselect->selectedVersion()->descriptor());
}
}
+
+void MainWindow::on_actionChangeInstLWJGLVersion_triggered()
+{
+ Instance *inst = selectedInstance();
+
+ if (!inst)
+ return;
+
+ LWJGLSelectDialog *lselect = new LWJGLSelectDialog(this);
+ if (lselect->exec())
+ {
+
+ }
+}
diff --git a/gui/mainwindow.h b/gui/mainwindow.h
index 192cdbc4..a9a4d395 100644
--- a/gui/mainwindow.h
+++ b/gui/mainwindow.h
@@ -99,6 +99,8 @@ private slots:
void taskStart(Task *task);
void taskEnd(Task *task);
+ void on_actionChangeInstLWJGLVersion_triggered();
+
public slots:
void instanceActivated ( QModelIndex );
diff --git a/libmultimc/CMakeLists.txt b/libmultimc/CMakeLists.txt
index 4ffa3173..0209f8a4 100644
--- a/libmultimc/CMakeLists.txt
+++ b/libmultimc/CMakeLists.txt
@@ -48,6 +48,7 @@ include/loginresponse.h
include/version.h
include/appsettings.h
include/minecraftprocess.h
+include/lwjglversionlist.h
)
SET(LIBINST_SOURCES
@@ -78,6 +79,7 @@ src/loginresponse.cpp
src/version.cpp
src/appsettings.cpp
src/minecraftprocess.cpp
+src/lwjglversionlist.cpp
)
# Set the include dir path.
diff --git a/libmultimc/include/lwjglversionlist.h b/libmultimc/include/lwjglversionlist.h
new file mode 100644
index 00000000..700c93d4
--- /dev/null
+++ b/libmultimc/include/lwjglversionlist.h
@@ -0,0 +1,128 @@
+/* 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.
+ */
+
+#ifndef LWJGLVERSIONLIST_H
+#define LWJGLVERSIONLIST_H
+
+#include <QObject>
+#include <QAbstractListModel>
+
+#include <QUrl>
+
+#include <QNetworkAccessManager>
+#include <QNetworkReply>
+
+#include "libmmc_config.h"
+
+class LIBMULTIMC_EXPORT LWJGLVersion : public QObject
+{
+ Q_OBJECT
+
+ /*!
+ * The name of the LWJGL version.
+ */
+ Q_PROPERTY(QString name READ name)
+
+ /*!
+ * The URL for this version of LWJGL.
+ */
+ Q_PROPERTY(QUrl url READ url)
+public:
+ LWJGLVersion(const QString &name, const QUrl &url, QObject *parent = 0) :
+ QObject(parent), m_name(name), m_url(url) { }
+
+ LWJGLVersion(const LWJGLVersion &other) :
+ QObject(other.parent()), m_name(other.name()), m_url(other.url()) { }
+
+ QString name() const { return m_name; }
+
+ QUrl url() const { return m_url; }
+
+protected:
+ QString m_name;
+ QUrl m_url;
+};
+
+class LIBMULTIMC_EXPORT LWJGLVersionList : public QAbstractListModel
+{
+ Q_OBJECT
+public:
+ explicit LWJGLVersionList(QObject *parent = 0);
+
+ static LWJGLVersionList &get();
+
+ bool isLoaded() { return m_vlist.length() > 0; }
+
+ const LWJGLVersion *getVersion(const QString &versionName);
+ LWJGLVersion &at(int index) { return m_vlist[index]; }
+ const LWJGLVersion &at(int index) const { return m_vlist[index]; }
+
+ int count() const { return m_vlist.length(); }
+
+ 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 { return count(); }
+ virtual int columnCount(const QModelIndex &parent) const;
+
+ virtual bool isLoading() const;
+ virtual bool errored() const { return m_errored; }
+
+ virtual QString lastErrorMsg() const { return m_lastErrorMsg; }
+
+public slots:
+ /*!
+ * Loads the version list.
+ * This is done asynchronously. On success, the loadListFinished() signal will
+ * be emitted. The list model will be reset as well, resulting in the modelReset()
+ * signal being emitted. Note that the model will be reset before loadListFinished() is emitted.
+ * If loading the list failed, the loadListFailed(QString msg),
+ * signal will be emitted.
+ */
+ virtual void loadList();
+
+signals:
+ /*!
+ * Emitted when the list either starts or finishes loading.
+ * \param loading Whether or not the list is loading.
+ */
+ void loadingStateUpdated(bool loading);
+
+ void loadListFinished();
+
+ void loadListFailed(QString msg);
+
+private:
+ QList<LWJGLVersion> m_vlist;
+
+ QNetworkReply *m_netReply;
+
+ QNetworkAccessManager netMgr;
+ QNetworkReply *reply;
+
+ bool m_loading;
+ bool m_errored;
+ QString m_lastErrorMsg;
+
+ void failed(QString msg);
+
+ void finished();
+
+ void setLoading(bool loading);
+
+private slots:
+ virtual void netRequestComplete();
+};
+
+#endif // LWJGLVERSIONLIST_H
diff --git a/libmultimc/src/lwjglversionlist.cpp b/libmultimc/src/lwjglversionlist.cpp
new file mode 100644
index 00000000..af5cf2f5
--- /dev/null
+++ b/libmultimc/src/lwjglversionlist.cpp
@@ -0,0 +1,204 @@
+/* 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/lwjglversionlist.h"
+
+#include <QtNetwork>
+
+#include <QtXml>
+
+#include <QRegExp>
+
+#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)
+{
+ setLoading(false);
+}
+
+QVariant LWJGLVersionList::data(const QModelIndex &index, int role) const
+{
+ if (!index.isValid())
+ return QVariant();
+
+ if (index.row() > count())
+ return QVariant();
+
+ const LWJGLVersion &version = at(index.row());
+
+ switch (role)
+ {
+ case Qt::DisplayRole:
+ return version.name();
+
+ case Qt::ToolTipRole:
+ return version.url().toString();
+
+ default:
+ return QVariant();
+ }
+}
+
+QVariant LWJGLVersionList::headerData(int section, Qt::Orientation orientation, int role) const
+{
+ switch (role)
+ {
+ case Qt::DisplayRole:
+ return "Version";
+
+ case Qt::ToolTipRole:
+ return "LWJGL version name.";
+
+ default:
+ return QVariant();
+ }
+}
+
+int LWJGLVersionList::columnCount(const QModelIndex &parent) const
+{
+ return 1;
+}
+
+bool LWJGLVersionList::isLoading() const
+{
+ return m_loading;
+}
+
+void LWJGLVersionList::loadList()
+{
+ Q_ASSERT_X(!m_loading, "loadList", "list is already loading (m_loading is true)");
+
+ setLoading(true);
+ reply = netMgr.get(QNetworkRequest(QUrl(RSS_URL)));
+ connect(reply, SIGNAL(finished()), SLOT(netRequestComplete()));
+}
+
+inline QDomElement getDomElementByTagName(QDomElement parent, QString tagname)
+{
+ QDomNodeList elementList = parent.elementsByTagName(tagname);
+ if (elementList.count())
+ return elementList.at(0).toElement();
+ else
+ return QDomElement();
+}
+
+void LWJGLVersionList::netRequestComplete()
+{
+ if (reply->error() == QNetworkReply::NoError)
+ {
+ QRegExp lwjglRegex("lwjgl-(([0-9]\\.?)+)\\.zip");
+ Q_ASSERT_X(lwjglRegex.isValid(), "load LWJGL list",
+ "LWJGL regex is invalid");
+
+ QDomDocument doc;
+
+ QString xmlErrorMsg;
+ int errorLine;
+ if (!doc.setContent(reply->readAll(), false, &xmlErrorMsg, &errorLine))
+ {
+ failed("Failed to load LWJGL list. XML error: " + xmlErrorMsg +
+ " at line " + QString::number(errorLine));
+ setLoading(false);
+ return;
+ }
+
+ QDomNodeList items = doc.elementsByTagName("item");
+
+ QList<LWJGLVersion> tempList;
+
+ for (int i = 0; i < items.length(); i++)
+ {
+ Q_ASSERT_X(items.at(i).isElement(), "load LWJGL list",
+ "XML element isn't an element... wat?");
+
+ QDomElement linkElement = getDomElementByTagName(items.at(i).toElement(), "link");
+ if (linkElement.isNull())
+ {
+ qWarning() << "Link element" << i << "in RSS feed doesn't exist! Skipping.";
+ continue;
+ }
+
+ QString link = linkElement.text();
+
+ // Make sure it's a download link.
+ if (link.endsWith("/download") && link.contains(lwjglRegex))
+ {
+ QString name = link.mid(lwjglRegex.indexIn(link));
+ // Subtract 4 here to remove the .zip file extension.
+ name = name.left(lwjglRegex.matchedLength() - 4);
+
+ QUrl url(link);
+ if (!url.isValid())
+ {
+ qWarning() << "LWJGL version URL isn't valid:" << link << "Skipping.";
+ continue;
+ }
+
+ tempList.append(LWJGLVersion(name, link));
+ }
+ }
+
+ beginResetModel();
+ m_vlist.swap(tempList);
+ endResetModel();
+
+ qDebug("Loaded LWJGL list.");
+ finished();
+ }
+ else
+ {
+ failed("Failed to load LWJGL list. Network error: " + reply->errorString());
+ }
+
+ setLoading(false);
+ reply->deleteLater();
+}
+
+const LWJGLVersion *LWJGLVersionList::getVersion(const QString &versionName)
+{
+ for (int i = 0; i < count(); i++)
+ {
+ if (at(i).name() == versionName)
+ return &at(i);
+ }
+ return NULL;
+}
+
+
+void LWJGLVersionList::failed(QString msg)
+{
+ qWarning() << msg;
+ emit loadListFailed(msg);
+}
+
+void LWJGLVersionList::finished()
+{
+ emit loadListFinished();
+}
+
+void LWJGLVersionList::setLoading(bool loading)
+{
+ m_loading = loading;
+ emit loadingStateUpdated(m_loading);
+}