NOISSUE Add world icons and world icon reset button

This commit is contained in:
Petr Mrázek 2020-08-22 01:34:55 +02:00
parent c6c9feb3a2
commit 8a0027c73a
7 changed files with 108 additions and 2 deletions

View File

@ -138,14 +138,31 @@ void World::repath(const QFileInfo &file)
m_folderName = file.fileName(); m_folderName = file.fileName();
if(file.isFile() && file.suffix() == "zip") if(file.isFile() && file.suffix() == "zip")
{ {
m_iconFile = QString();
readFromZip(file); readFromZip(file);
} }
else if(file.isDir()) else if(file.isDir())
{ {
QFileInfo assumedIconPath(file.absoluteFilePath() + "/icon.png");
if(assumedIconPath.exists()) {
m_iconFile = assumedIconPath.absoluteFilePath();
}
readFromFS(file); readFromFS(file);
} }
} }
bool World::resetIcon()
{
if(m_iconFile.isNull()) {
return false;
}
if(QFile(m_iconFile).remove()) {
m_iconFile = QString();
return true;
}
return false;
}
void World::readFromFS(const QFileInfo &file) void World::readFromFS(const QFileInfo &file)
{ {
auto bytes = getLevelDatDataFromFS(file); auto bytes = getLevelDatDataFromFS(file);

View File

@ -40,6 +40,10 @@ public:
{ {
return m_actualName; return m_actualName;
} }
QString iconFile() const
{
return m_iconFile;
}
QDateTime lastPlayed() const QDateTime lastPlayed() const
{ {
return m_lastPlayed; return m_lastPlayed;
@ -70,6 +74,8 @@ public:
bool replace(World &with); bool replace(World &with);
// change the world's filesystem path (used by world lists for *MAGIC* purposes) // change the world's filesystem path (used by world lists for *MAGIC* purposes)
void repath(const QFileInfo &file); void repath(const QFileInfo &file);
// remove the icon file, if any
bool resetIcon();
bool rename(const QString &to); bool rename(const QString &to);
bool install(const QString &to, const QString &name= QString()); bool install(const QString &to, const QString &name= QString());
@ -88,6 +94,7 @@ protected:
QString m_containerOffsetPath; QString m_containerOffsetPath;
QString m_folderName; QString m_folderName;
QString m_actualName; QString m_actualName;
QString m_iconFile;
QDateTime levelDatTime; QDateTime levelDatTime;
QDateTime m_lastPlayed; QDateTime m_lastPlayed;
int64_t m_randomSeed = 0; int64_t m_randomSeed = 0;

View File

@ -136,6 +136,19 @@ bool WorldList::deleteWorlds(int first, int last)
return true; return true;
} }
bool WorldList::resetIcon(int row)
{
if (row >= worlds.size() || row < 0)
return false;
World &m = worlds[row];
if(m.resetIcon()) {
emit dataChanged(index(row), index(row), {WorldList::IconFileRole});
return true;
}
return false;
}
int WorldList::columnCount(const QModelIndex &parent) const int WorldList::columnCount(const QModelIndex &parent) const
{ {
return 3; return 3;
@ -195,6 +208,10 @@ QVariant WorldList::data(const QModelIndex &index, int role) const
{ {
return world.lastPlayed(); return world.lastPlayed();
} }
case IconFileRole:
{
return world.iconFile();
}
default: default:
return QVariant(); return QVariant();
} }

View File

@ -44,7 +44,8 @@ public:
SeedRole, SeedRole,
NameRole, NameRole,
GameModeRole, GameModeRole,
LastPlayedRole LastPlayedRole,
IconFileRole
}; };
WorldList(const QString &dir); WorldList(const QString &dir);
@ -81,6 +82,9 @@ public:
/// Deletes the mod at the given index. /// Deletes the mod at the given index.
virtual bool deleteWorld(int index); virtual bool deleteWorld(int index);
/// Removes the world icon, if any
virtual bool resetIcon(int index);
/// Deletes all the selected mods /// Deletes all the selected mods
virtual bool deleteWorlds(int first, int last); virtual bool deleteWorlds(int first, int last);

View File

@ -31,6 +31,33 @@
#include <QProcess> #include <QProcess>
#include <FileSystem.h> #include <FileSystem.h>
class WorldListProxyModel : public QSortFilterProxyModel
{
Q_OBJECT
public:
WorldListProxyModel(QObject *parent) : QSortFilterProxyModel(parent) {}
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const
{
QModelIndex sourceIndex = mapToSource(index);
if (index.column() == 0 && role == Qt::DecorationRole)
{
WorldList *worlds = qobject_cast<WorldList *>(sourceModel());
auto iconFile = worlds->data(sourceIndex, WorldList::IconFileRole).toString();
if(iconFile.isNull()) {
// NOTE: Minecraft uses the same placeholder for servers AND worlds
return MMC->getThemedIcon("unknown_server");
}
return QIcon(iconFile);
}
return sourceIndex.data(role);
}
};
WorldListPage::WorldListPage(BaseInstance *inst, std::shared_ptr<WorldList> worlds, QWidget *parent) WorldListPage::WorldListPage(BaseInstance *inst, std::shared_ptr<WorldList> worlds, QWidget *parent)
: QMainWindow(parent), m_inst(inst), ui(new Ui::WorldListPage), m_worlds(worlds) : QMainWindow(parent), m_inst(inst), ui(new Ui::WorldListPage), m_worlds(worlds)
{ {
@ -38,13 +65,14 @@ WorldListPage::WorldListPage(BaseInstance *inst, std::shared_ptr<WorldList> worl
ui->toolBar->insertSpacer(ui->actionRefresh); ui->toolBar->insertSpacer(ui->actionRefresh);
QSortFilterProxyModel * proxy = new QSortFilterProxyModel(this); WorldListProxyModel * proxy = new WorldListProxyModel(this);
proxy->setSortCaseSensitivity(Qt::CaseInsensitive); proxy->setSortCaseSensitivity(Qt::CaseInsensitive);
proxy->setSourceModel(m_worlds.get()); proxy->setSourceModel(m_worlds.get());
ui->worldTreeView->setSortingEnabled(true); ui->worldTreeView->setSortingEnabled(true);
ui->worldTreeView->setModel(proxy); ui->worldTreeView->setModel(proxy);
ui->worldTreeView->installEventFilter(this); ui->worldTreeView->installEventFilter(this);
ui->worldTreeView->setContextMenuPolicy(Qt::CustomContextMenu); ui->worldTreeView->setContextMenuPolicy(Qt::CustomContextMenu);
ui->worldTreeView->setIconSize(QSize(64,64));
connect(ui->worldTreeView, &QTreeView::customContextMenuRequested, this, &WorldListPage::ShowContextMenu); connect(ui->worldTreeView, &QTreeView::customContextMenuRequested, this, &WorldListPage::ShowContextMenu);
auto head = ui->worldTreeView->header(); auto head = ui->worldTreeView->header();
@ -142,6 +170,19 @@ void WorldListPage::on_actionView_Folder_triggered()
DesktopServices::openDirectory(m_worlds->dir().absolutePath(), true); DesktopServices::openDirectory(m_worlds->dir().absolutePath(), true);
} }
void WorldListPage::on_actionReset_Icon_triggered()
{
auto proxiedIndex = getSelectedWorld();
if(!proxiedIndex.isValid())
return;
if(m_worlds->resetIcon(proxiedIndex.row())) {
ui->actionReset_Icon->setEnabled(false);
}
}
QModelIndex WorldListPage::getSelectedWorld() QModelIndex WorldListPage::getSelectedWorld()
{ {
auto index = ui->worldTreeView->selectionModel()->currentIndex(); auto index = ui->worldTreeView->selectionModel()->currentIndex();
@ -255,6 +296,8 @@ void WorldListPage::worldChanged(const QModelIndex &current, const QModelIndex &
ui->actionRemove->setEnabled(enable); ui->actionRemove->setEnabled(enable);
ui->actionCopy->setEnabled(enable); ui->actionCopy->setEnabled(enable);
ui->actionRename->setEnabled(enable); ui->actionRename->setEnabled(enable);
bool hasIcon = !index.data(WorldList::IconFileRole).isNull();
ui->actionReset_Icon->setEnabled(enable && hasIcon);
} }
void WorldListPage::on_actionAdd_triggered() void WorldListPage::on_actionAdd_triggered()
@ -342,3 +385,5 @@ void WorldListPage::on_actionRefresh_triggered()
{ {
m_worlds->update(); m_worlds->update();
} }
#include "WorldListPage.moc"

View File

@ -90,6 +90,7 @@ private slots:
void on_actionRename_triggered(); void on_actionRename_triggered();
void on_actionRefresh_triggered(); void on_actionRefresh_triggered();
void on_actionView_Folder_triggered(); void on_actionView_Folder_triggered();
void on_actionReset_Icon_triggered();
void worldChanged(const QModelIndex &current, const QModelIndex &previous); void worldChanged(const QModelIndex &current, const QModelIndex &previous);
void mceditState(LoggedProcess::State state); void mceditState(LoggedProcess::State state);

View File

@ -41,6 +41,12 @@
<property name="alternatingRowColors"> <property name="alternatingRowColors">
<bool>true</bool> <bool>true</bool>
</property> </property>
<property name="rootIsDecorated">
<bool>false</bool>
</property>
<property name="itemsExpandable">
<bool>false</bool>
</property>
<property name="sortingEnabled"> <property name="sortingEnabled">
<bool>true</bool> <bool>true</bool>
</property> </property>
@ -79,6 +85,7 @@
<addaction name="actionCopy"/> <addaction name="actionCopy"/>
<addaction name="actionRemove"/> <addaction name="actionRemove"/>
<addaction name="actionMCEdit"/> <addaction name="actionMCEdit"/>
<addaction name="actionReset_Icon"/>
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="actionCopy_Seed"/> <addaction name="actionCopy_Seed"/>
<addaction name="actionRefresh"/> <addaction name="actionRefresh"/>
@ -124,6 +131,14 @@
<string>View Folder</string> <string>View Folder</string>
</property> </property>
</action> </action>
<action name="actionReset_Icon">
<property name="text">
<string>Reset Icon</string>
</property>
<property name="toolTip">
<string>Remove world icon to make the game re-generate it on next load.</string>
</property>
</action>
</widget> </widget>
<customwidgets> <customwidgets>
<customwidget> <customwidget>