mirror of
https://github.com/PrismLauncher/PrismLauncher.git
synced 2026-06-29 01:54:20 +03:00
all worlds list will now join correct instance for each world
This commit is contained in:
parent
0ceb218180
commit
3a6ae78bc6
5 changed files with 66 additions and 56 deletions
|
|
@ -46,7 +46,9 @@
|
|||
#include <QUuid>
|
||||
#include <Qt>
|
||||
|
||||
MultiWorldList::MultiWorldList(const QList<QString>& dirs, QList<BaseInstance*> instances) : QAbstractListModel(), m_instances(instances)
|
||||
#include "MinecraftInstance.h"
|
||||
|
||||
MultiWorldList::MultiWorldList(const QList<QString>& dirs, const QList<BaseInstance*>& instances) : QAbstractListModel(), m_instances(instances)
|
||||
{
|
||||
for (QString dir : dirs) {
|
||||
m_dirs.append(dir);
|
||||
|
|
@ -105,9 +107,10 @@ bool MultiWorldList::update()
|
|||
if (!isValid())
|
||||
return false;
|
||||
|
||||
QList<World> newWorlds;
|
||||
QList<InstanceWorld> newWorlds;
|
||||
|
||||
for (QDir dir : m_dirs) {
|
||||
for (BaseInstance* inst : m_instances) {
|
||||
QDir dir = dynamic_cast<MinecraftInstance*>(inst)->worldDir();
|
||||
dir.refresh();
|
||||
auto folderContents = dir.entryInfoList();
|
||||
// if there are any untracked files...
|
||||
|
|
@ -117,7 +120,7 @@ bool MultiWorldList::update()
|
|||
|
||||
World w(entry);
|
||||
if (w.isValid()) {
|
||||
newWorlds.append(w);
|
||||
newWorlds.append(InstanceWorld(w, inst));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -134,16 +137,24 @@ void MultiWorldList::directoryChanged(QString)
|
|||
update();
|
||||
}
|
||||
|
||||
bool MultiWorldList::isValid() //account for all directories
|
||||
bool MultiWorldList::isValid()
|
||||
{
|
||||
return m_dirs[0].exists() && m_dirs[0].isReadable();
|
||||
bool valid = true;
|
||||
|
||||
for (const QDir& dir : m_dirs) {
|
||||
if (!(dir.exists() && dir.isReadable())) {
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
QList<QString> MultiWorldList::instDirPaths() const
|
||||
{
|
||||
QList<QString> dirList;
|
||||
|
||||
for (BaseInstance* instance : m_instances) {
|
||||
for (BaseInstance* instance : m_instances) { //use m_dirs??? iy
|
||||
dirList.append(QFileInfo(instance->instanceRoot()).absoluteFilePath());
|
||||
}
|
||||
|
||||
|
|
@ -154,7 +165,7 @@ bool MultiWorldList::deleteWorld(int index)
|
|||
{
|
||||
if (index >= m_worlds.size() || index < 0)
|
||||
return false;
|
||||
World& m = m_worlds[index];
|
||||
World& m = m_worlds[index].world;
|
||||
if (m.destroy()) {
|
||||
beginRemoveRows(QModelIndex(), index, index);
|
||||
m_worlds.removeAt(index);
|
||||
|
|
@ -168,7 +179,7 @@ bool MultiWorldList::deleteWorld(int index)
|
|||
bool MultiWorldList::deleteWorlds(int first, int last)
|
||||
{
|
||||
for (int i = first; i <= last; i++) {
|
||||
World& m = m_worlds[i];
|
||||
World& m = m_worlds[i].world;
|
||||
m.destroy();
|
||||
}
|
||||
beginRemoveRows(QModelIndex(), first, last);
|
||||
|
|
@ -182,7 +193,7 @@ bool MultiWorldList::resetIcon(int row)
|
|||
{
|
||||
if (row >= m_worlds.size() || row < 0)
|
||||
return false;
|
||||
World& m = m_worlds[row];
|
||||
World& m = m_worlds[row].world;
|
||||
if (m.resetIcon()) {
|
||||
QModelIndex modelIndex = index(row, NameColumn);
|
||||
emit dataChanged(modelIndex, modelIndex, { MultiWorldList::IconFileRole });
|
||||
|
|
@ -209,29 +220,29 @@ QVariant MultiWorldList::data(const QModelIndex& index, int role) const
|
|||
|
||||
QLocale locale;
|
||||
|
||||
auto& world = m_worlds[row];
|
||||
auto& instanceWorld = m_worlds[row];
|
||||
switch (role) {
|
||||
case Qt::DisplayRole:
|
||||
switch (column) {
|
||||
case NameColumn:
|
||||
return world.name();
|
||||
return instanceWorld.world.name();
|
||||
|
||||
case GameModeColumn:
|
||||
return world.gameType().toTranslatedString();
|
||||
return instanceWorld.world.gameType().toTranslatedString();
|
||||
|
||||
case LastPlayedColumn:
|
||||
return world.lastPlayed();
|
||||
return instanceWorld.world.lastPlayed();
|
||||
|
||||
case SizeColumn:
|
||||
return locale.formattedDataSize(world.bytes());
|
||||
return locale.formattedDataSize(instanceWorld.world.bytes());
|
||||
|
||||
case InfoColumn:
|
||||
for (QString path : instDirPaths()) { //use canonical paths instead of for loops? iy
|
||||
if (world.isSymLinkUnder(path)) {
|
||||
if (instanceWorld.world.isSymLinkUnder(path)) {
|
||||
return tr("This world is symbolically linked from elsewhere.");
|
||||
}
|
||||
}
|
||||
if (world.isMoreThanOneHardLink()) {
|
||||
if (instanceWorld.world.isMoreThanOneHardLink()) {
|
||||
return tr("\nThis world is hard linked elsewhere.");
|
||||
}
|
||||
return "";
|
||||
|
|
@ -241,44 +252,44 @@ QVariant MultiWorldList::data(const QModelIndex& index, int role) const
|
|||
|
||||
case Qt::UserRole:
|
||||
if (column == SizeColumn)
|
||||
return QVariant::fromValue<qlonglong>(world.bytes());
|
||||
return QVariant::fromValue<qlonglong>(instanceWorld.world.bytes());
|
||||
return data(index, Qt::DisplayRole);
|
||||
|
||||
case Qt::ToolTipRole: {
|
||||
if (column == InfoColumn) {
|
||||
for (QString path : instDirPaths()) { //use canonical paths instead of for loops? iy
|
||||
if (world.isSymLinkUnder(path)) {
|
||||
if (instanceWorld.world.isSymLinkUnder(path)) {
|
||||
return tr("Warning: This world is symbolically linked from elsewhere. Editing it will also change the original."
|
||||
"\nCanonical Path: %1")
|
||||
.arg(world.canonicalFilePath());
|
||||
.arg(instanceWorld.world.canonicalFilePath());
|
||||
}
|
||||
}
|
||||
if (world.isMoreThanOneHardLink()) {
|
||||
if (instanceWorld.world.isMoreThanOneHardLink()) {
|
||||
return tr("Warning: This world is hard linked elsewhere. Editing it will also change the original.");
|
||||
}
|
||||
}
|
||||
return world.folderName();
|
||||
return instanceWorld.world.folderName();
|
||||
}
|
||||
case ObjectRole: {
|
||||
return QVariant::fromValue<void*>((void*)&world);
|
||||
return QVariant::fromValue<void*>((void*)&instanceWorld);
|
||||
}
|
||||
case FolderRole: {
|
||||
return QDir::toNativeSeparators(QDir(world.canonicalFilePath()).absoluteFilePath(world.folderName())); //test if canonical file path works iy
|
||||
return QDir::toNativeSeparators(QDir(instanceWorld.world.canonicalFilePath()).absoluteFilePath(instanceWorld.world.folderName())); //test if canonical file path works iy
|
||||
}
|
||||
case SeedRole: {
|
||||
return QVariant::fromValue<qlonglong>(world.seed());
|
||||
return QVariant::fromValue<qlonglong>(instanceWorld.world.seed());
|
||||
}
|
||||
case NameRole: {
|
||||
return world.name();
|
||||
return instanceWorld.world.name();
|
||||
}
|
||||
case LastPlayedRole: {
|
||||
return world.lastPlayed();
|
||||
return instanceWorld.world.lastPlayed();
|
||||
}
|
||||
case SizeRole: {
|
||||
return QVariant::fromValue<qlonglong>(world.bytes());
|
||||
return QVariant::fromValue<qlonglong>(instanceWorld.world.bytes());
|
||||
}
|
||||
case IconFileRole: {
|
||||
return world.iconFile();
|
||||
return instanceWorld.world.iconFile();
|
||||
}
|
||||
default:
|
||||
return QVariant();
|
||||
|
|
@ -345,7 +356,7 @@ QMimeData* MultiWorldList::mimeData(const QModelIndexList& indexes) const
|
|||
if (row < 0 || row >= this->m_worlds.size())
|
||||
continue;
|
||||
|
||||
const World& world = m_worlds[row];
|
||||
const World& world = m_worlds[row].world;
|
||||
|
||||
if (!world.isValid() || !world.isOnFS())
|
||||
continue;
|
||||
|
|
@ -446,7 +457,7 @@ int64_t MultiWorldList::calculateWorldSize(const QFileInfo& file)
|
|||
void MultiWorldList::loadWorldsAsync()
|
||||
{
|
||||
for (int i = 0; i < m_worlds.size(); ++i) {
|
||||
auto file = m_worlds.at(i).container();
|
||||
auto file = m_worlds.at(i).world.container();
|
||||
int row = i;
|
||||
QThreadPool::globalInstance()->start([this, file, row]() mutable {
|
||||
auto size = calculateWorldSize(file);
|
||||
|
|
@ -454,8 +465,8 @@ void MultiWorldList::loadWorldsAsync()
|
|||
QMetaObject::invokeMethod(
|
||||
this,
|
||||
[this, size, row, file]() {
|
||||
if (row < m_worlds.size() && m_worlds[row].container() == file) {
|
||||
m_worlds[row].setSize(size);
|
||||
if (row < m_worlds.size() && m_worlds[row].world.container() == file) {
|
||||
m_worlds[row].world.setSize(size);
|
||||
|
||||
// Notify views
|
||||
QModelIndex modelIndex = index(row, SizeColumn);
|
||||
|
|
|
|||
|
|
@ -25,6 +25,11 @@
|
|||
|
||||
class QFileSystemWatcher;
|
||||
|
||||
struct InstanceWorld {
|
||||
World world;
|
||||
BaseInstance* instance;
|
||||
};
|
||||
|
||||
class MultiWorldList : public QAbstractListModel {
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
|
@ -32,7 +37,7 @@ class MultiWorldList : public QAbstractListModel {
|
|||
|
||||
enum Roles { ObjectRole = Qt::UserRole + 1, FolderRole, SeedRole, NameRole, GameModeRole, LastPlayedRole, SizeRole, IconFileRole };
|
||||
|
||||
MultiWorldList(const QList<QString>& dirs, QList<BaseInstance*> instances);
|
||||
MultiWorldList(const QList<QString>& dirs, const QList<BaseInstance*>& instances);
|
||||
|
||||
virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
|
||||
|
||||
|
|
@ -42,7 +47,7 @@ class MultiWorldList : public QAbstractListModel {
|
|||
|
||||
size_t size() const { return m_worlds.size(); };
|
||||
bool empty() const { return size() == 0; }
|
||||
World& operator[](size_t index) { return m_worlds[index]; }
|
||||
World& operator[](size_t index) { return m_worlds[index].world; }
|
||||
|
||||
/// Reloads the mod list and returns true if the list changed.
|
||||
virtual bool update();
|
||||
|
|
@ -83,7 +88,7 @@ class MultiWorldList : public QAbstractListModel {
|
|||
|
||||
QList<QString> instDirPaths() const;
|
||||
|
||||
const QList<World>& allWorlds() const { return m_worlds; }
|
||||
const QList<InstanceWorld>& allWorlds() const { return m_worlds; }
|
||||
|
||||
private slots:
|
||||
void directoryChanged(QString path);
|
||||
|
|
@ -97,5 +102,5 @@ class MultiWorldList : public QAbstractListModel {
|
|||
QFileSystemWatcher* m_watcher;
|
||||
bool m_isWatching;
|
||||
QList<QDir> m_dirs;
|
||||
QList<World> m_worlds;
|
||||
QList<InstanceWorld> m_worlds;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -339,7 +339,6 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), ui(new Ui::MainWi
|
|||
// Create the all worlds widget
|
||||
{
|
||||
QList<BaseInstance*> allInstances = APPLICATION->instances()->getAllInstances();
|
||||
qDebug() << "iy initially" << allInstances.length();
|
||||
QList<QString> dirs;
|
||||
for (BaseInstance* inst : allInstances) {
|
||||
dirs.append(dynamic_cast<MinecraftInstance*>(inst)->worldDir());
|
||||
|
|
@ -347,7 +346,7 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), ui(new Ui::MainWi
|
|||
|
||||
allWorlds = new MultiWorldList(dirs, allInstances);
|
||||
allWorlds->update();
|
||||
allWorldsPage = new MultiWorldListPage(dynamic_cast<MinecraftInstance*>(allInstances[0]), allWorlds); //shouldnt be only one instance iy
|
||||
allWorldsPage = new MultiWorldListPage(allWorlds);
|
||||
|
||||
ui->horizontalLayout->addWidget(allWorldsPage);
|
||||
}
|
||||
|
|
@ -945,10 +944,7 @@ void MainWindow::addInstance(const QString& url, const QMap<QString, QString>& e
|
|||
instanceFromInstanceTask(creationTask);
|
||||
}
|
||||
|
||||
//clean this up iy - fix ghosting issue and only joining one world despite which one you click
|
||||
|
||||
QList<BaseInstance*> allInstances = APPLICATION->instances()->getAllInstances();
|
||||
qDebug() << "iy finally " << allInstances.length();
|
||||
QList<QString> dirs;
|
||||
for (BaseInstance* inst : allInstances) {
|
||||
dirs.append(dynamic_cast<MinecraftInstance*>(inst)->worldDir());
|
||||
|
|
@ -956,8 +952,9 @@ void MainWindow::addInstance(const QString& url, const QMap<QString, QString>& e
|
|||
|
||||
allWorlds = new MultiWorldList(dirs, allInstances);
|
||||
allWorlds->update();
|
||||
auto newAllWorldsPage = new MultiWorldListPage(dynamic_cast<MinecraftInstance*>(allInstances[0]), allWorlds); //shouldnt be only one instance iy
|
||||
auto newAllWorldsPage = new MultiWorldListPage(allWorlds);
|
||||
ui->horizontalLayout->replaceWidget(allWorldsPage, newAllWorldsPage);
|
||||
delete allWorldsPage;
|
||||
allWorldsPage = newAllWorldsPage;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -86,14 +86,14 @@ class MultiWorldListProxyModel : public QSortFilterProxyModel {
|
|||
}
|
||||
};
|
||||
|
||||
MultiWorldListPage::MultiWorldListPage(MinecraftInstance* inst, MultiWorldList* worlds, QWidget* parent) //require all instances instead of just one iy
|
||||
: QMainWindow(parent), m_inst(inst), ui(new Ui::MultiWorldListPage), m_worlds(worlds)
|
||||
MultiWorldListPage::MultiWorldListPage(MultiWorldList* worlds, QWidget* parent)
|
||||
: QMainWindow(parent), ui(new Ui::MultiWorldListPage), m_worlds(worlds)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
ui->toolBar->insertSpacer(ui->actionRefresh);
|
||||
|
||||
MultiWorldListProxyModel* proxy = new MultiWorldListProxyModel(this);
|
||||
auto* proxy = new MultiWorldListProxyModel(this);
|
||||
proxy->setSortCaseSensitivity(Qt::CaseInsensitive);
|
||||
proxy->setSourceModel(m_worlds);
|
||||
proxy->setSortRole(Qt::UserRole);
|
||||
|
|
@ -195,7 +195,7 @@ void MultiWorldListPage::on_actionRemove_triggered()
|
|||
tr("You are about to delete \"%1\".\n"
|
||||
"The world may be gone forever (A LONG TIME).\n\n"
|
||||
"Are you sure?")
|
||||
.arg(m_worlds->allWorlds().at(proxiedIndex.row()).name()),
|
||||
.arg(m_worlds->allWorlds().at(proxiedIndex.row()).world.name()),
|
||||
QMessageBox::Warning, QMessageBox::Yes | QMessageBox::No, QMessageBox::No)
|
||||
->exec();
|
||||
|
||||
|
|
@ -237,9 +237,9 @@ void MultiWorldListPage::on_actionData_Packs_triggered()
|
|||
GenericPageProvider provider(dialog->windowTitle());
|
||||
|
||||
bool isIndexed = !APPLICATION->settings()->get("ModMetadataDisabled").toBool();
|
||||
m_datapackModel.reset(new DataPackFolderModel(folder, m_inst, isIndexed, true));
|
||||
m_datapackModel.reset(new DataPackFolderModel(folder, m_worlds->allWorlds()[0].instance, isIndexed, true)); //don't use instance 0 iy
|
||||
|
||||
provider.addPageCreator([this] { return new DataPackPage(m_inst, m_datapackModel.get(), this); });
|
||||
provider.addPageCreator([this] { return new DataPackPage(m_worlds->allWorlds()[0].instance, m_datapackModel.get(), this); }); //no instance 0 iy
|
||||
|
||||
auto layout = new QVBoxLayout(dialog);
|
||||
|
||||
|
|
@ -402,7 +402,7 @@ void MultiWorldListPage::on_actionAdd_triggered()
|
|||
|
||||
bool MultiWorldListPage::isWorldSafe(QModelIndex)
|
||||
{
|
||||
return !m_inst->isRunning();
|
||||
return !m_worlds->allWorlds()[0].instance->isRunning(); //don't use instance 0 iy
|
||||
}
|
||||
|
||||
bool MultiWorldListPage::worldSafetyNagQuestion(const QString& actionType)
|
||||
|
|
@ -471,8 +471,8 @@ void MultiWorldListPage::on_actionJoin_triggered()
|
|||
return;
|
||||
}
|
||||
auto worldVariant = m_worlds->data(index, MultiWorldList::ObjectRole);
|
||||
auto world = (World*)worldVariant.value<void*>();
|
||||
APPLICATION->launch(m_inst, LaunchMode::Normal, std::make_shared<MinecraftTarget>(MinecraftTarget::parse(world->folderName(), true)));
|
||||
auto world = (InstanceWorld*)worldVariant.value<void*>();
|
||||
APPLICATION->launch(world->instance, LaunchMode::Normal, std::make_shared<MinecraftTarget>(MinecraftTarget::parse(world->world.folderName(), true)));
|
||||
}
|
||||
|
||||
#include "MultiWorldListPage.moc"
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ class MultiWorldListPage : public QMainWindow, public BasePage {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MultiWorldListPage(MinecraftInstance* inst, MultiWorldList* worlds, QWidget* parent = 0);
|
||||
explicit MultiWorldListPage(MultiWorldList* worlds, QWidget* parent = 0);
|
||||
virtual ~MultiWorldListPage();
|
||||
|
||||
virtual QString displayName() const override { return tr("Worlds"); }
|
||||
|
|
@ -70,9 +70,6 @@ class MultiWorldListPage : public QMainWindow, public BasePage {
|
|||
bool worldListFilter(QKeyEvent* ev);
|
||||
QMenu* createPopupMenu() override;
|
||||
|
||||
protected:
|
||||
MinecraftInstance* m_inst;
|
||||
|
||||
private:
|
||||
QModelIndex getSelectedWorld();
|
||||
bool isWorldSafe(QModelIndex index);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue