Merge pull request #2166 from Trial97/ftb2

Updated ftb app import instance detection
This commit is contained in:
Alexandru Ionut Tripon 2024-06-10 00:45:22 +03:00 committed by GitHub
commit 154f4811c0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 77 additions and 44 deletions

View File

@ -21,6 +21,7 @@
#include "ui_ImportFTBPage.h" #include "ui_ImportFTBPage.h"
#include <QFileDialog> #include <QFileDialog>
#include <QFileInfo>
#include <QWidget> #include <QWidget>
#include "FileSystem.h" #include "FileSystem.h"
#include "ListModel.h" #include "ListModel.h"
@ -58,8 +59,8 @@ ImportFTBPage::ImportFTBPage(NewInstanceDialog* dialog, QWidget* parent) : QWidg
connect(ui->searchEdit, &QLineEdit::textChanged, this, &ImportFTBPage::triggerSearch); connect(ui->searchEdit, &QLineEdit::textChanged, this, &ImportFTBPage::triggerSearch);
connect(ui->browseButton, &QPushButton::clicked, this, [this] { connect(ui->browseButton, &QPushButton::clicked, this, [this] {
auto path = listModel->getPath(); QString dir = QFileDialog::getExistingDirectory(this, tr("Select FTBApp instances directory"), listModel->getUserPath(),
QString dir = QFileDialog::getExistingDirectory(this, tr("Select FTBApp instances directory"), path, QFileDialog::ShowDirsOnly); QFileDialog::ShowDirsOnly);
if (!dir.isEmpty()) if (!dir.isEmpty())
listModel->setPath(dir); listModel->setPath(dir);
}); });

View File

@ -24,45 +24,76 @@
#include <QIcon> #include <QIcon>
#include <QProcessEnvironment> #include <QProcessEnvironment>
#include "Application.h" #include "Application.h"
#include "Exception.h"
#include "FileSystem.h" #include "FileSystem.h"
#include "Json.h"
#include "StringUtils.h" #include "StringUtils.h"
#include "modplatform/import_ftb/PackHelpers.h" #include "modplatform/import_ftb/PackHelpers.h"
#include "ui/widgets/ProjectItem.h" #include "ui/widgets/ProjectItem.h"
namespace FTBImportAPP { namespace FTBImportAPP {
QString getStaticPath() QString getFTBRoot()
{ {
QString partialPath; QString partialPath = QDir::homePath();
#if defined(Q_OS_OSX) #if defined(Q_OS_OSX)
partialPath = FS::PathCombine(QDir::homePath(), "Library/Application Support"); partialPath = FS::PathCombine(partialPath, "Library/Application Support");
#elif defined(Q_OS_WIN32)
partialPath = QProcessEnvironment::systemEnvironment().value("LOCALAPPDATA", "");
#else
partialPath = QDir::homePath();
#endif #endif
return FS::PathCombine(partialPath, ".ftba"); return FS::PathCombine(partialPath, ".ftba");
} }
static const QString FTB_APP_PATH = FS::PathCombine(getStaticPath(), "instances"); QString getDynamicPath()
{
auto settingsPath = FS::PathCombine(getFTBRoot(), "storage", "settings.json");
if (!QFileInfo::exists(settingsPath))
settingsPath = FS::PathCombine(getFTBRoot(), "bin", "settings.json");
if (!QFileInfo::exists(settingsPath)) {
qWarning() << "The ftb app setings doesn't exist.";
return {};
}
try {
auto doc = Json::requireDocument(FS::read(settingsPath));
return Json::requireString(Json::requireObject(doc), "instanceLocation");
} catch (const Exception& e) {
qCritical() << "Could not read ftb settings file: " << e.cause();
}
return {};
}
ListModel::ListModel(QObject* parent) : QAbstractListModel(parent), m_instances_path(getDynamicPath()) {}
void ListModel::update() void ListModel::update()
{ {
beginResetModel(); beginResetModel();
modpacks.clear(); m_modpacks.clear();
QString instancesPath = getPath(); auto wasPathAdded = [this](QString path) {
if (auto instancesInfo = QFileInfo(instancesPath); instancesInfo.exists() && instancesInfo.isDir()) { for (auto pack : m_modpacks) {
QDirIterator directoryIterator(instancesPath, QDir::Dirs | QDir::NoDotAndDotDot | QDir::Readable | QDir::Hidden, if (pack.path == path)
return true;
}
return false;
};
auto scanPath = [this, wasPathAdded](QString path) {
if (path.isEmpty())
return;
if (auto instancesInfo = QFileInfo(path); !instancesInfo.exists() || !instancesInfo.isDir())
return;
QDirIterator directoryIterator(path, QDir::Dirs | QDir::NoDotAndDotDot | QDir::Readable | QDir::Hidden,
QDirIterator::FollowSymlinks); QDirIterator::FollowSymlinks);
while (directoryIterator.hasNext()) { while (directoryIterator.hasNext()) {
auto modpack = parseDirectory(directoryIterator.next()); auto currentPath = directoryIterator.next();
if (!wasPathAdded(currentPath)) {
auto modpack = parseDirectory(currentPath);
if (!modpack.path.isEmpty()) if (!modpack.path.isEmpty())
modpacks.append(modpack); m_modpacks.append(modpack);
} }
} else {
qDebug() << "Couldn't find ftb instances folder: " << instancesPath;
} }
};
scanPath(APPLICATION->settings()->get("FTBAppInstancesPath").toString());
scanPath(m_instances_path);
endResetModel(); endResetModel();
} }
@ -70,11 +101,11 @@ void ListModel::update()
QVariant ListModel::data(const QModelIndex& index, int role) const QVariant ListModel::data(const QModelIndex& index, int role) const
{ {
int pos = index.row(); int pos = index.row();
if (pos >= modpacks.size() || pos < 0 || !index.isValid()) { if (pos >= m_modpacks.size() || pos < 0 || !index.isValid()) {
return QVariant(); return QVariant();
} }
auto pack = modpacks.at(pos); auto pack = m_modpacks.at(pos);
if (role == Qt::ToolTipRole) { if (role == Qt::ToolTipRole) {
} }
@ -110,9 +141,9 @@ QVariant ListModel::data(const QModelIndex& index, int role) const
FilterModel::FilterModel(QObject* parent) : QSortFilterProxyModel(parent) FilterModel::FilterModel(QObject* parent) : QSortFilterProxyModel(parent)
{ {
currentSorting = Sorting::ByGameVersion; m_currentSorting = Sorting::ByGameVersion;
sortings.insert(tr("Sort by Name"), Sorting::ByName); m_sortings.insert(tr("Sort by Name"), Sorting::ByName);
sortings.insert(tr("Sort by Game Version"), Sorting::ByGameVersion); m_sortings.insert(tr("Sort by Game Version"), Sorting::ByGameVersion);
} }
bool FilterModel::lessThan(const QModelIndex& left, const QModelIndex& right) const bool FilterModel::lessThan(const QModelIndex& left, const QModelIndex& right) const
@ -120,12 +151,12 @@ bool FilterModel::lessThan(const QModelIndex& left, const QModelIndex& right) co
Modpack leftPack = sourceModel()->data(left, Qt::UserRole).value<Modpack>(); Modpack leftPack = sourceModel()->data(left, Qt::UserRole).value<Modpack>();
Modpack rightPack = sourceModel()->data(right, Qt::UserRole).value<Modpack>(); Modpack rightPack = sourceModel()->data(right, Qt::UserRole).value<Modpack>();
if (currentSorting == Sorting::ByGameVersion) { if (m_currentSorting == Sorting::ByGameVersion) {
Version lv(leftPack.mcVersion); Version lv(leftPack.mcVersion);
Version rv(rightPack.mcVersion); Version rv(rightPack.mcVersion);
return lv < rv; return lv < rv;
} else if (currentSorting == Sorting::ByName) { } else if (m_currentSorting == Sorting::ByName) {
return StringUtils::naturalCompare(leftPack.name, rightPack.name, Qt::CaseSensitive) >= 0; return StringUtils::naturalCompare(leftPack.name, rightPack.name, Qt::CaseSensitive) >= 0;
} }
@ -136,39 +167,39 @@ bool FilterModel::lessThan(const QModelIndex& left, const QModelIndex& right) co
bool FilterModel::filterAcceptsRow([[maybe_unused]] int sourceRow, [[maybe_unused]] const QModelIndex& sourceParent) const bool FilterModel::filterAcceptsRow([[maybe_unused]] int sourceRow, [[maybe_unused]] const QModelIndex& sourceParent) const
{ {
if (searchTerm.isEmpty()) { if (m_searchTerm.isEmpty()) {
return true; return true;
} }
QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent); QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
Modpack pack = sourceModel()->data(index, Qt::UserRole).value<Modpack>(); Modpack pack = sourceModel()->data(index, Qt::UserRole).value<Modpack>();
return pack.name.contains(searchTerm, Qt::CaseInsensitive); return pack.name.contains(m_searchTerm, Qt::CaseInsensitive);
} }
void FilterModel::setSearchTerm(const QString term) void FilterModel::setSearchTerm(const QString term)
{ {
searchTerm = term.trimmed(); m_searchTerm = term.trimmed();
invalidate(); invalidate();
} }
const QMap<QString, FilterModel::Sorting> FilterModel::getAvailableSortings() const QMap<QString, FilterModel::Sorting> FilterModel::getAvailableSortings()
{ {
return sortings; return m_sortings;
} }
QString FilterModel::translateCurrentSorting() QString FilterModel::translateCurrentSorting()
{ {
return sortings.key(currentSorting); return m_sortings.key(m_currentSorting);
} }
void FilterModel::setSorting(Sorting s) void FilterModel::setSorting(Sorting s)
{ {
currentSorting = s; m_currentSorting = s;
invalidate(); invalidate();
} }
FilterModel::Sorting FilterModel::getCurrentSorting() FilterModel::Sorting FilterModel::getCurrentSorting()
{ {
return currentSorting; return m_currentSorting;
} }
void ListModel::setPath(QString path) void ListModel::setPath(QString path)
{ {
@ -176,11 +207,11 @@ void ListModel::setPath(QString path)
update(); update();
} }
QString ListModel::getPath() QString ListModel::getUserPath()
{ {
auto path = APPLICATION->settings()->get("FTBAppInstancesPath").toString(); auto path = APPLICATION->settings()->get("FTBAppInstancesPath").toString();
if (path.isEmpty() || !QFileInfo(path).exists()) if (path.isEmpty())
path = FTB_APP_PATH; path = m_instances_path;
return path; return path;
} }
} // namespace FTBImportAPP } // namespace FTBImportAPP

View File

@ -42,28 +42,29 @@ class FilterModel : public QSortFilterProxyModel {
bool lessThan(const QModelIndex& left, const QModelIndex& right) const override; bool lessThan(const QModelIndex& left, const QModelIndex& right) const override;
private: private:
QMap<QString, Sorting> sortings; QMap<QString, Sorting> m_sortings;
Sorting currentSorting; Sorting m_currentSorting;
QString searchTerm; QString m_searchTerm;
}; };
class ListModel : public QAbstractListModel { class ListModel : public QAbstractListModel {
Q_OBJECT Q_OBJECT
public: public:
ListModel(QObject* parent) : QAbstractListModel(parent) {} ListModel(QObject* parent);
virtual ~ListModel() = default; virtual ~ListModel() = default;
int rowCount(const QModelIndex& parent) const { return modpacks.size(); } int rowCount(const QModelIndex& parent) const { return m_modpacks.size(); }
int columnCount(const QModelIndex& parent) const { return 1; } int columnCount(const QModelIndex& parent) const { return 1; }
QVariant data(const QModelIndex& index, int role) const; QVariant data(const QModelIndex& index, int role) const;
void update(); void update();
QString getPath(); QString getUserPath();
void setPath(QString path); void setPath(QString path);
private: private:
ModpackList modpacks; ModpackList m_modpacks;
const QString m_instances_path;
}; };
} // namespace FTBImportAPP } // namespace FTBImportAPP