Implemented version lists.

Further work on this is still needed. Currently there is no sorting or filtering of any kind. In addition,
changes need to be made to fix issues with bad ETags since the current system here is based on MultiMC 4's
version list system before it was fixed.
This commit is contained in:
Andrew 2013-03-28 11:33:31 -05:00
parent ad70e3fd4c
commit 168ed3e8e5
12 changed files with 352 additions and 12 deletions

View File

@ -172,6 +172,7 @@ gui/aboutdialog.h
gui/consolewindow.h
gui/instancemodel.h
gui/instancedelegate.h
gui/versionselectdialog.h
multimc_pragma.h
@ -200,6 +201,7 @@ gui/aboutdialog.cpp
gui/consolewindow.cpp
gui/instancemodel.cpp
gui/instancedelegate.cpp
gui/versionselectdialog.cpp
java/javautils.cpp
java/annotations.cpp
@ -217,6 +219,7 @@ gui/taskdialog.ui
gui/browserdialog.ui
gui/aboutdialog.ui
gui/consolewindow.ui
gui/versionselectdialog.ui
)

View File

@ -39,6 +39,7 @@
#include "gui/taskdialog.h"
#include "gui/browserdialog.h"
#include "gui/aboutdialog.h"
#include "gui/versionselectdialog.h"
#include "kcategorizedview.h"
#include "kcategorydrawer.h"
@ -260,3 +261,15 @@ void openInDefaultProgram ( QString filename )
{
QDesktopServices::openUrl ( "file:///" + QFileInfo ( filename ).absolutePath() );
}
void MainWindow::on_actionChangeInstMCVersion_triggered()
{
if (view->selectionModel()->selectedIndexes().count() < 1)
return;
QModelIndex index = view->selectionModel()->selectedIndexes().at(0);
Instance *inst = (Instance *)index.data(InstanceModel::InstancePointerRole).value<void *>();
VersionSelectDialog *vselect = new VersionSelectDialog(inst->versionList(), this);
vselect->exec();
}

View File

@ -73,6 +73,8 @@ private slots:
void on_actionMakeDesktopShortcut_triggered();
void on_actionChangeInstMCVersion_triggered();
void doLogin( QString inst, const QString& errorMsg = "" );

View File

@ -0,0 +1,62 @@
/* 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 "versionselectdialog.h"
#include "ui_versionselectdialog.h"
#include <QHeaderView>
#include <gui/taskdialog.h>
#include <instversionlist.h>
#include <task.h>
VersionSelectDialog::VersionSelectDialog(InstVersionList *vlist, QWidget *parent) :
QDialog(parent),
ui(new Ui::VersionSelectDialog)
{
ui->setupUi(this);
m_vlist = vlist;
ui->listView->setModel(m_vlist);
ui->listView->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
ui->listView->header()->setSectionResizeMode(0, QHeaderView::Stretch);
}
VersionSelectDialog::~VersionSelectDialog()
{
delete ui;
}
int VersionSelectDialog::exec()
{
QDialog::open();
if (!m_vlist->isLoaded())
loadList();
return QDialog::exec();
}
void VersionSelectDialog::loadList()
{
TaskDialog *taskDlg = new TaskDialog(this);
Task *loadTask = m_vlist->getLoadTask();
loadTask->setParent(taskDlg);
taskDlg->exec(loadTask);
}
void VersionSelectDialog::on_refreshButton_clicked()
{
loadList();
}

50
gui/versionselectdialog.h Normal file
View File

@ -0,0 +1,50 @@
/* 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 VERSIONSELECTDIALOG_H
#define VERSIONSELECTDIALOG_H
#include <QDialog>
class InstVersionList;
namespace Ui
{
class VersionSelectDialog;
}
class VersionSelectDialog : public QDialog
{
Q_OBJECT
public:
explicit VersionSelectDialog(InstVersionList *vlist, QWidget *parent = 0);
~VersionSelectDialog();
virtual int exec();
//! Starts a task that loads the list.
void loadList();
private slots:
void on_refreshButton_clicked();
private:
Ui::VersionSelectDialog *ui;
InstVersionList *m_vlist;
};
#endif // VERSIONSELECTDIALOG_H

100
gui/versionselectdialog.ui Normal file
View File

@ -0,0 +1,100 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>VersionSelectDialog</class>
<widget class="QDialog" name="VersionSelectDialog">
<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="QTreeView" name="listView">
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="rootIsDecorated">
<bool>false</bool>
</property>
<property name="itemsExpandable">
<bool>false</bool>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<attribute name="headerCascadingSectionResizes">
<bool>true</bool>
</attribute>
<attribute name="headerStretchLastSection">
<bool>false</bool>
</attribute>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="refreshButton">
<property name="toolTip">
<string>Reloads the version list.</string>
</property>
<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>VersionSelectDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>257</x>
<y>290</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>VersionSelectDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>325</x>
<y>290</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -40,16 +40,15 @@ public:
* \breif Returns this InstVersion's name.
* This is displayed to the user in the GUI and is usually just the version number ("1.4.7"), for example.
*/
virtual QString name() const = 0;
/*!
* \brief Returns this InstVersion's name.
* \brief Returns this InstVersion's type name.
* This is usually displayed to the user in the GUI and specifies what
* kind of version this is. For example: it could be "Snapshot",
* "Latest Version", "MCNostalgia", etc.
*/
virtual QString type() const = 0;
virtual QString typeName() const = 0;
//! Returns the version list that this InstVersion is a part of.
virtual InstVersionList *versionList() const;

View File

@ -17,6 +17,8 @@
#define INSTVERSIONLIST_H
#include <QObject>
#include <QVariant>
#include <QAbstractListModel>
#include "libmmc_config.h"
@ -29,8 +31,13 @@ class Task;
* 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 LIBMULTIMC_EXPORT InstVersionList : public QObject
class LIBMULTIMC_EXPORT InstVersionList : public QAbstractListModel
{
Q_OBJECT
public:
@ -39,6 +46,7 @@ public:
/*!
* \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;
@ -52,6 +60,14 @@ public:
//! 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.

View File

@ -17,7 +17,7 @@
#include "instversion.h"
InstVersionList::InstVersionList(QObject *parent) :
QObject(parent)
QAbstractListModel(parent)
{
}
@ -30,3 +30,96 @@ const InstVersion *InstVersionList::findVersion(const QString &descriptor)
}
return NULL;
}
// Column Enum
enum VListColumns
{
// First column - Name
NameColumn = 0,
// Second column - Type
TypeColumn,
// Column count
ColCount
};
QVariant InstVersionList::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
if (index.row() > count())
return QVariant();
const InstVersion *version = at(index.row());
switch (role)
{
case Qt::DisplayRole:
switch (index.column())
{
case NameColumn:
return version->name();
case TypeColumn:
return version->typeName();
default:
return QVariant();
}
case Qt::ToolTipRole:
return version->descriptor();
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";
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 ColCount;
}

View File

@ -63,10 +63,10 @@ QString StdInstVersion::name() const
return m_name;
}
QString StdInstVersion::type() const
QString StdInstVersion::typeName() const
{
if (m_linkedVersion)
return m_linkedVersion->type();
return m_linkedVersion->typeName();
switch (versionType())
{

View File

@ -55,14 +55,14 @@ public:
virtual QString descriptor() const;
virtual QString name() const;
virtual QString type() const;
virtual QString typeName() const;
virtual qint64 timestamp() const;
virtual QString downloadURL() const;
virtual bool hasLWJGL() const;
virtual QString etag() const;
virtual VersionType versionType() const;
virtual void setVersionType(VersionType type);
virtual void setVersionType(VersionType typeName);
virtual bool isMeta() const;

View File

@ -45,7 +45,7 @@
#define MCN_URLBASE "http://sonicrules.org/mcnweb.py"
// When this is defined, prints the entire version list to qDebug() after loading.
#define PRINT_VERSIONS
//#define PRINT_VERSIONS
StdInstVersionList vList;
@ -90,7 +90,7 @@ void StdInstVersionList::printToStdOut()
qDebug() << "Version " << version->name();
qDebug() << "\tDownload: " << version->downloadURL();
qDebug() << "\tTimestamp: " << version->timestamp();
qDebug() << "\tType: " << version->type();
qDebug() << "\tType: " << version->typeName();
qDebug() << "----------------------------------------------";
}
}
@ -157,8 +157,10 @@ void StdInstVListLoadTask::finalize()
// Now we swap the list we loaded into the actual version list.
// This applies our changes to the version list immediately and still gives us
// access to the old list so that we can delete the objects in it and free their memory.
// By doing this, we cause the version list to update immediately.
// By doing this, we cause the version list to update as quickly as possible.
m_list->beginResetModel();
m_list->m_vlist.swap(tempList);
m_list->endResetModel();
// We called swap, so all the data that was in the version list previously is now in
// tempList (and vice-versa). Now we just free the memory.