Merge remote-tracking branch 'upstream/develop' into feature/instance-shortcuts
This commit is contained in:
commit
ba46ff6692
27
.github/workflows/build.yml
vendored
27
.github/workflows/build.yml
vendored
@ -7,6 +7,10 @@ on:
|
|||||||
description: Type of build (Debug, Release, RelWithDebInfo, MinSizeRel)
|
description: Type of build (Debug, Release, RelWithDebInfo, MinSizeRel)
|
||||||
type: string
|
type: string
|
||||||
default: Debug
|
default: Debug
|
||||||
|
is_qt_cached:
|
||||||
|
description: Enable Qt caching or not
|
||||||
|
type: string
|
||||||
|
default: true
|
||||||
secrets:
|
secrets:
|
||||||
SPARKLE_ED25519_KEY:
|
SPARKLE_ED25519_KEY:
|
||||||
description: Private key for signing Sparkle updates
|
description: Private key for signing Sparkle updates
|
||||||
@ -102,14 +106,6 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
submodules: 'true'
|
submodules: 'true'
|
||||||
|
|
||||||
- name: Initialize CodeQL
|
|
||||||
if: runner.os == 'Linux' && matrix.qt_ver == 6
|
|
||||||
uses: github/codeql-action/init@v2
|
|
||||||
with:
|
|
||||||
config-file: ./.github/codeql/codeql-config.yml
|
|
||||||
queries: security-and-quality
|
|
||||||
languages: cpp, java
|
|
||||||
|
|
||||||
- name: 'Setup MSYS2'
|
- name: 'Setup MSYS2'
|
||||||
if: runner.os == 'Windows' && matrix.msystem != ''
|
if: runner.os == 'Windows' && matrix.msystem != ''
|
||||||
uses: msys2/setup-msys2@v2
|
uses: msys2/setup-msys2@v2
|
||||||
@ -200,8 +196,7 @@ jobs:
|
|||||||
arch: ${{ matrix.qt_arch }}
|
arch: ${{ matrix.qt_arch }}
|
||||||
modules: ${{ matrix.qt_modules }}
|
modules: ${{ matrix.qt_modules }}
|
||||||
tools: ${{ matrix.qt_tools }}
|
tools: ${{ matrix.qt_tools }}
|
||||||
cache: true
|
cache: ${{ inputs.is_qt_cached }}
|
||||||
cache-key-prefix: ${{ matrix.qt_host }}-${{ matrix.qt_version }}-"${{ matrix.qt_modules }}"-qt_cache
|
|
||||||
|
|
||||||
- name: Prepare AppImage (Linux)
|
- name: Prepare AppImage (Linux)
|
||||||
if: runner.os == 'Linux' && matrix.qt_ver != 5
|
if: runner.os == 'Linux' && matrix.qt_ver != 5
|
||||||
@ -292,14 +287,6 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
ctest -E "^example64|example$" --test-dir build --output-on-failure -C ${{ inputs.build_type }}
|
ctest -E "^example64|example$" --test-dir build --output-on-failure -C ${{ inputs.build_type }}
|
||||||
|
|
||||||
##
|
|
||||||
# CODE SCAN
|
|
||||||
##
|
|
||||||
|
|
||||||
- name: Perform CodeQL Analysis
|
|
||||||
if: runner.os == 'Linux' && matrix.qt_ver == 6
|
|
||||||
uses: github/codeql-action/analyze@v2
|
|
||||||
|
|
||||||
##
|
##
|
||||||
# PACKAGE BUILDS
|
# PACKAGE BUILDS
|
||||||
##
|
##
|
||||||
@ -510,10 +497,10 @@ jobs:
|
|||||||
echo "VERSION=$ver_short" >> $GITHUB_ENV
|
echo "VERSION=$ver_short" >> $GITHUB_ENV
|
||||||
- name: Package Snap (Linux)
|
- name: Package Snap (Linux)
|
||||||
id: snapcraft
|
id: snapcraft
|
||||||
if: runner.os == 'Linux' && matrix.qt_ver != 5
|
if: runner.os == 'Linux' && inputs.build_type == 'Debug'
|
||||||
uses: snapcore/action-build@v1
|
uses: snapcore/action-build@v1
|
||||||
- name: Upload Snap (Linux)
|
- name: Upload Snap (Linux)
|
||||||
if: runner.os == 'Linux' && matrix.qt_ver != 5
|
if: runner.os == 'Linux' && inputs.build_type == 'Debug'
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: prismlauncher_${{ env.VERSION }}_amd64.snap
|
name: prismlauncher_${{ env.VERSION }}_amd64.snap
|
||||||
|
35
.github/workflows/codeql.yml
vendored
Normal file
35
.github/workflows/codeql.yml
vendored
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
name: "CodeQL Code Scanning"
|
||||||
|
|
||||||
|
on: [ push, pull_request, workflow_dispatch ]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
CodeQL:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
submodules: 'true'
|
||||||
|
|
||||||
|
- name: Initialize CodeQL
|
||||||
|
uses: github/codeql-action/init@v2
|
||||||
|
with:
|
||||||
|
config-file: ./.github/codeql/codeql-config.yml
|
||||||
|
queries: security-and-quality
|
||||||
|
languages: cpp, java
|
||||||
|
|
||||||
|
- name: Install Dependencies
|
||||||
|
run:
|
||||||
|
sudo apt-get -y update
|
||||||
|
|
||||||
|
sudo apt-get -y install ninja-build extra-cmake-modules scdoc qtbase5-dev qtchooser qt5-qmake qtbase5-dev-tools libqt5core5a libqt5network5 libqt5gui5
|
||||||
|
|
||||||
|
- name: Configure and Build
|
||||||
|
run: |
|
||||||
|
cmake -S . -B build -DCMAKE_INSTALL_PREFIX=/usr -DLauncher_QT_VERSION_MAJOR=5 -G Ninja
|
||||||
|
|
||||||
|
cmake --build build
|
||||||
|
|
||||||
|
- name: Perform CodeQL Analysis
|
||||||
|
uses: github/codeql-action/analyze@v2
|
1
.github/workflows/trigger_builds.yml
vendored
1
.github/workflows/trigger_builds.yml
vendored
@ -30,5 +30,6 @@ jobs:
|
|||||||
uses: ./.github/workflows/build.yml
|
uses: ./.github/workflows/build.yml
|
||||||
with:
|
with:
|
||||||
build_type: Debug
|
build_type: Debug
|
||||||
|
is_qt_cached: true
|
||||||
secrets:
|
secrets:
|
||||||
SPARKLE_ED25519_KEY: ${{ secrets.SPARKLE_ED25519_KEY }}
|
SPARKLE_ED25519_KEY: ${{ secrets.SPARKLE_ED25519_KEY }}
|
||||||
|
1
.github/workflows/trigger_release.yml
vendored
1
.github/workflows/trigger_release.yml
vendored
@ -12,6 +12,7 @@ jobs:
|
|||||||
uses: ./.github/workflows/build.yml
|
uses: ./.github/workflows/build.yml
|
||||||
with:
|
with:
|
||||||
build_type: Release
|
build_type: Release
|
||||||
|
is_qt_cached: false
|
||||||
secrets:
|
secrets:
|
||||||
SPARKLE_ED25519_KEY: ${{ secrets.SPARKLE_ED25519_KEY }}
|
SPARKLE_ED25519_KEY: ${{ secrets.SPARKLE_ED25519_KEY }}
|
||||||
|
|
||||||
|
@ -151,7 +151,7 @@ public:
|
|||||||
void copyManagedPack(BaseInstance& other);
|
void copyManagedPack(BaseInstance& other);
|
||||||
|
|
||||||
/// guess log level from a line of game log
|
/// guess log level from a line of game log
|
||||||
virtual MessageLevel::Enum guessLevel(const QString &line, MessageLevel::Enum level)
|
virtual MessageLevel::Enum guessLevel([[maybe_unused]] const QString &line, MessageLevel::Enum level)
|
||||||
{
|
{
|
||||||
return level;
|
return level;
|
||||||
};
|
};
|
||||||
|
@ -95,12 +95,12 @@ BaseVersionList::RoleList BaseVersionList::providesRoles() const
|
|||||||
int BaseVersionList::rowCount(const QModelIndex &parent) const
|
int BaseVersionList::rowCount(const QModelIndex &parent) const
|
||||||
{
|
{
|
||||||
// Return count
|
// Return count
|
||||||
return count();
|
return parent.isValid() ? 0 : count();
|
||||||
}
|
}
|
||||||
|
|
||||||
int BaseVersionList::columnCount(const QModelIndex &parent) const
|
int BaseVersionList::columnCount(const QModelIndex &parent) const
|
||||||
{
|
{
|
||||||
return 1;
|
return parent.isValid() ? 0 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
QHash<int, QByteArray> BaseVersionList::roleNames() const
|
QHash<int, QByteArray> BaseVersionList::roleNames() const
|
||||||
|
@ -311,14 +311,14 @@ QModelIndex VersionProxyModel::index(int row, int column, const QModelIndex &par
|
|||||||
|
|
||||||
int VersionProxyModel::columnCount(const QModelIndex &parent) const
|
int VersionProxyModel::columnCount(const QModelIndex &parent) const
|
||||||
{
|
{
|
||||||
return m_columns.size();
|
return parent.isValid() ? 0 : m_columns.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
int VersionProxyModel::rowCount(const QModelIndex &parent) const
|
int VersionProxyModel::rowCount(const QModelIndex &parent) const
|
||||||
{
|
{
|
||||||
if(sourceModel())
|
if(sourceModel())
|
||||||
{
|
{
|
||||||
return sourceModel()->rowCount();
|
return sourceModel()->rowCount(parent);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -242,7 +242,7 @@ Qt::DropActions IconList::supportedDropActions() const
|
|||||||
return Qt::CopyAction;
|
return Qt::CopyAction;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IconList::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)
|
bool IconList::dropMimeData(const QMimeData *data, Qt::DropAction action, [[maybe_unused]] int row, [[maybe_unused]] int column, [[maybe_unused]] const QModelIndex &parent)
|
||||||
{
|
{
|
||||||
if (action == Qt::IgnoreAction)
|
if (action == Qt::IgnoreAction)
|
||||||
return true;
|
return true;
|
||||||
@ -302,7 +302,7 @@ QVariant IconList::data(const QModelIndex &index, int role) const
|
|||||||
|
|
||||||
int IconList::rowCount(const QModelIndex &parent) const
|
int IconList::rowCount(const QModelIndex &parent) const
|
||||||
{
|
{
|
||||||
return icons.size();
|
return parent.isValid() ? 0 : icons.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
void IconList::installIcons(const QStringList &iconFiles)
|
void IconList::installIcons(const QStringList &iconFiles)
|
||||||
|
@ -58,11 +58,11 @@ QVariant Index::data(const QModelIndex &index, int role) const
|
|||||||
}
|
}
|
||||||
int Index::rowCount(const QModelIndex &parent) const
|
int Index::rowCount(const QModelIndex &parent) const
|
||||||
{
|
{
|
||||||
return m_lists.size();
|
return parent.isValid() ? 0 : m_lists.size();
|
||||||
}
|
}
|
||||||
int Index::columnCount(const QModelIndex &parent) const
|
int Index::columnCount(const QModelIndex &parent) const
|
||||||
{
|
{
|
||||||
return 1;
|
return parent.isValid() ? 0 : 1;
|
||||||
}
|
}
|
||||||
QVariant Index::headerData(int section, Qt::Orientation orientation, int role) const
|
QVariant Index::headerData(int section, Qt::Orientation orientation, int role) const
|
||||||
{
|
{
|
||||||
|
@ -60,11 +60,6 @@ struct Require
|
|||||||
QString suggests;
|
QString suggests;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline Q_DECL_PURE_FUNCTION uint qHash(const Require &key, uint seed = 0) Q_DECL_NOTHROW
|
|
||||||
{
|
|
||||||
return qHash(key.uid, seed);
|
|
||||||
}
|
|
||||||
|
|
||||||
using RequireSet = std::set<Require>;
|
using RequireSet = std::set<Require>;
|
||||||
|
|
||||||
void parseIndex(const QJsonObject &obj, Index *ptr);
|
void parseIndex(const QJsonObject &obj, Index *ptr);
|
||||||
|
@ -613,7 +613,7 @@ QVariant PackProfile::data(const QModelIndex &index, int role) const
|
|||||||
|
|
||||||
bool PackProfile::setData(const QModelIndex& index, const QVariant& value, int role)
|
bool PackProfile::setData(const QModelIndex& index, const QVariant& value, int role)
|
||||||
{
|
{
|
||||||
if (!index.isValid() || index.row() < 0 || index.row() >= rowCount(index))
|
if (!index.isValid() || index.row() < 0 || index.row() >= rowCount(index.parent()))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -675,12 +675,12 @@ Qt::ItemFlags PackProfile::flags(const QModelIndex &index) const
|
|||||||
|
|
||||||
int PackProfile::rowCount(const QModelIndex &parent) const
|
int PackProfile::rowCount(const QModelIndex &parent) const
|
||||||
{
|
{
|
||||||
return d->components.size();
|
return parent.isValid() ? 0 : d->components.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
int PackProfile::columnCount(const QModelIndex &parent) const
|
int PackProfile::columnCount(const QModelIndex &parent) const
|
||||||
{
|
{
|
||||||
return NUM_COLUMNS;
|
return parent.isValid() ? 0 : NUM_COLUMNS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PackProfile::move(const int index, const MoveDirection direction)
|
void PackProfile::move(const int index, const MoveDirection direction)
|
||||||
|
@ -104,7 +104,7 @@ public:
|
|||||||
class ImplicitRule : public Rule
|
class ImplicitRule : public Rule
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
virtual bool applies(const Library *, const RuntimeContext & runtimeContext)
|
virtual bool applies(const Library *, [[maybe_unused]] const RuntimeContext & runtimeContext)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -173,7 +173,7 @@ bool WorldList::resetIcon(int row)
|
|||||||
|
|
||||||
int WorldList::columnCount(const QModelIndex &parent) const
|
int WorldList::columnCount(const QModelIndex &parent) const
|
||||||
{
|
{
|
||||||
return 4;
|
return parent.isValid()? 0 : 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant WorldList::data(const QModelIndex &index, int role) const
|
QVariant WorldList::data(const QModelIndex &index, int role) const
|
||||||
@ -398,8 +398,8 @@ void WorldList::installWorld(QFileInfo filename)
|
|||||||
w.install(m_dir.absolutePath());
|
w.install(m_dir.absolutePath());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WorldList::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column,
|
bool WorldList::dropMimeData(const QMimeData *data, Qt::DropAction action, [[maybe_unused]] int row, [[maybe_unused]] int column,
|
||||||
const QModelIndex &parent)
|
[[maybe_unused]] const QModelIndex &parent)
|
||||||
{
|
{
|
||||||
if (action == Qt::IgnoreAction)
|
if (action == Qt::IgnoreAction)
|
||||||
return true;
|
return true;
|
||||||
|
@ -54,7 +54,7 @@ public:
|
|||||||
|
|
||||||
virtual int rowCount(const QModelIndex &parent = QModelIndex()) const
|
virtual int rowCount(const QModelIndex &parent = QModelIndex()) const
|
||||||
{
|
{
|
||||||
return size();
|
return parent.isValid() ? 0 : static_cast<int>(size());
|
||||||
};
|
};
|
||||||
virtual QVariant headerData(int section, Qt::Orientation orientation,
|
virtual QVariant headerData(int section, Qt::Orientation orientation,
|
||||||
int role = Qt::DisplayRole) const;
|
int role = Qt::DisplayRole) const;
|
||||||
|
@ -408,20 +408,20 @@ QVariant AccountList::headerData(int section, Qt::Orientation orientation, int r
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int AccountList::rowCount(const QModelIndex &) const
|
int AccountList::rowCount(const QModelIndex &parent) const
|
||||||
{
|
{
|
||||||
// Return count
|
// Return count
|
||||||
return count();
|
return parent.isValid() ? 0 : count();
|
||||||
}
|
}
|
||||||
|
|
||||||
int AccountList::columnCount(const QModelIndex &) const
|
int AccountList::columnCount(const QModelIndex &parent) const
|
||||||
{
|
{
|
||||||
return NUM_COLUMNS;
|
return parent.isValid() ? 0 : NUM_COLUMNS;
|
||||||
}
|
}
|
||||||
|
|
||||||
Qt::ItemFlags AccountList::flags(const QModelIndex &index) const
|
Qt::ItemFlags AccountList::flags(const QModelIndex &index) const
|
||||||
{
|
{
|
||||||
if (index.row() < 0 || index.row() >= rowCount(index) || !index.isValid())
|
if (index.row() < 0 || index.row() >= rowCount(index.parent()) || !index.isValid())
|
||||||
{
|
{
|
||||||
return Qt::NoItemFlags;
|
return Qt::NoItemFlags;
|
||||||
}
|
}
|
||||||
|
@ -144,7 +144,7 @@ QVariant ModFolderModel::headerData(int section, Qt::Orientation orientation, in
|
|||||||
|
|
||||||
int ModFolderModel::columnCount(const QModelIndex &parent) const
|
int ModFolderModel::columnCount(const QModelIndex &parent) const
|
||||||
{
|
{
|
||||||
return NUM_COLUMNS;
|
return parent.isValid() ? 0 : NUM_COLUMNS;
|
||||||
}
|
}
|
||||||
|
|
||||||
Task* ModFolderModel::createUpdateTask()
|
Task* ModFolderModel::createUpdateTask()
|
||||||
|
@ -426,7 +426,7 @@ QVariant ResourceFolderModel::data(const QModelIndex& index, int role) const
|
|||||||
bool ResourceFolderModel::setData(const QModelIndex& index, const QVariant& value, int role)
|
bool ResourceFolderModel::setData(const QModelIndex& index, const QVariant& value, int role)
|
||||||
{
|
{
|
||||||
int row = index.row();
|
int row = index.row();
|
||||||
if (row < 0 || row >= rowCount(index) || !index.isValid())
|
if (row < 0 || row >= rowCount(index.parent()) || !index.isValid())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (role == Qt::CheckStateRole)
|
if (role == Qt::CheckStateRole)
|
||||||
|
@ -90,8 +90,8 @@ class ResourceFolderModel : public QAbstractListModel {
|
|||||||
/* Basic columns */
|
/* Basic columns */
|
||||||
enum Columns { ACTIVE_COLUMN = 0, NAME_COLUMN, DATE_COLUMN, NUM_COLUMNS };
|
enum Columns { ACTIVE_COLUMN = 0, NAME_COLUMN, DATE_COLUMN, NUM_COLUMNS };
|
||||||
|
|
||||||
[[nodiscard]] int rowCount(const QModelIndex& = {}) const override { return size(); }
|
[[nodiscard]] int rowCount(const QModelIndex& parent = {}) const override { return parent.isValid() ? 0 : static_cast<int>(size()); }
|
||||||
[[nodiscard]] int columnCount(const QModelIndex& = {}) const override { return NUM_COLUMNS; };
|
[[nodiscard]] int columnCount(const QModelIndex& parent = {}) const override { return parent.isValid() ? 0 : NUM_COLUMNS; };
|
||||||
|
|
||||||
[[nodiscard]] Qt::DropActions supportedDropActions() const override;
|
[[nodiscard]] Qt::DropActions supportedDropActions() const override;
|
||||||
|
|
||||||
@ -176,7 +176,7 @@ class ResourceFolderModel : public QAbstractListModel {
|
|||||||
* if the resource is complex and has more stuff to parse.
|
* if the resource is complex and has more stuff to parse.
|
||||||
*/
|
*/
|
||||||
virtual void onParseSucceeded(int ticket, QString resource_id);
|
virtual void onParseSucceeded(int ticket, QString resource_id);
|
||||||
virtual void onParseFailed(int ticket, QString resource_id) {}
|
virtual void onParseFailed(int ticket, QString resource_id) { Q_UNUSED(ticket); Q_UNUSED(resource_id); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Represents the relationship between a column's index (represented by the list index), and it's sorting key.
|
// Represents the relationship between a column's index (represented by the list index), and it's sorting key.
|
||||||
|
@ -137,7 +137,7 @@ QVariant ResourcePackFolderModel::headerData(int section, Qt::Orientation orient
|
|||||||
|
|
||||||
int ResourcePackFolderModel::columnCount(const QModelIndex& parent) const
|
int ResourcePackFolderModel::columnCount(const QModelIndex& parent) const
|
||||||
{
|
{
|
||||||
return NUM_COLUMNS;
|
return parent.isValid() ? 0 : NUM_COLUMNS;
|
||||||
}
|
}
|
||||||
|
|
||||||
Task* ResourcePackFolderModel::createUpdateTask()
|
Task* ResourcePackFolderModel::createUpdateTask()
|
||||||
|
@ -121,7 +121,7 @@ ModDetails ReadMCModTOML(QByteArray contents)
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
auto modsTable = tomlModsTable0->as_table();
|
auto modsTable = tomlModsTable0->as_table();
|
||||||
if (!tomlModsTable0) {
|
if (!modsTable) {
|
||||||
qWarning() << "Corrupted mods.toml? [[mods]] was not a table!";
|
qWarning() << "Corrupted mods.toml? [[mods]] was not a table!";
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@
|
|||||||
auto MetaEntry::getFullPath() -> QString
|
auto MetaEntry::getFullPath() -> QString
|
||||||
{
|
{
|
||||||
// FIXME: make local?
|
// FIXME: make local?
|
||||||
return FS::PathCombine(basePath, relativePath);
|
return FS::PathCombine(m_basePath, m_relativePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpMetaCache::HttpMetaCache(QString path) : QObject(), m_index_file(path)
|
HttpMetaCache::HttpMetaCache(QString path) : QObject(), m_index_file(path)
|
||||||
@ -99,7 +99,7 @@ auto HttpMetaCache::resolveEntry(QString base, QString resource_path, QString ex
|
|||||||
return staleEntry(base, resource_path);
|
return staleEntry(base, resource_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!expected_etag.isEmpty() && expected_etag != entry->etag) {
|
if (!expected_etag.isEmpty() && expected_etag != entry->m_etag) {
|
||||||
// if the etag doesn't match expected, we disown the entry
|
// if the etag doesn't match expected, we disown the entry
|
||||||
selected_base.entry_list.remove(resource_path);
|
selected_base.entry_list.remove(resource_path);
|
||||||
return staleEntry(base, resource_path);
|
return staleEntry(base, resource_path);
|
||||||
@ -107,17 +107,17 @@ auto HttpMetaCache::resolveEntry(QString base, QString resource_path, QString ex
|
|||||||
|
|
||||||
// if the file changed, check md5sum
|
// if the file changed, check md5sum
|
||||||
qint64 file_last_changed = finfo.lastModified().toUTC().toMSecsSinceEpoch();
|
qint64 file_last_changed = finfo.lastModified().toUTC().toMSecsSinceEpoch();
|
||||||
if (file_last_changed != entry->local_changed_timestamp) {
|
if (file_last_changed != entry->m_local_changed_timestamp) {
|
||||||
QFile input(real_path);
|
QFile input(real_path);
|
||||||
input.open(QIODevice::ReadOnly);
|
input.open(QIODevice::ReadOnly);
|
||||||
QString md5sum = QCryptographicHash::hash(input.readAll(), QCryptographicHash::Md5).toHex().constData();
|
QString md5sum = QCryptographicHash::hash(input.readAll(), QCryptographicHash::Md5).toHex().constData();
|
||||||
if (entry->md5sum != md5sum) {
|
if (entry->m_md5sum != md5sum) {
|
||||||
selected_base.entry_list.remove(resource_path);
|
selected_base.entry_list.remove(resource_path);
|
||||||
return staleEntry(base, resource_path);
|
return staleEntry(base, resource_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
// md5sums matched... keep entry and save the new state to file
|
// md5sums matched... keep entry and save the new state to file
|
||||||
entry->local_changed_timestamp = file_last_changed;
|
entry->m_local_changed_timestamp = file_last_changed;
|
||||||
SaveEventually();
|
SaveEventually();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,23 +130,23 @@ auto HttpMetaCache::resolveEntry(QString base, QString resource_path, QString ex
|
|||||||
}
|
}
|
||||||
|
|
||||||
// entry passed all the checks we cared about.
|
// entry passed all the checks we cared about.
|
||||||
entry->basePath = getBasePath(base);
|
entry->m_basePath = getBasePath(base);
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto HttpMetaCache::updateEntry(MetaEntryPtr stale_entry) -> bool
|
auto HttpMetaCache::updateEntry(MetaEntryPtr stale_entry) -> bool
|
||||||
{
|
{
|
||||||
if (!m_entries.contains(stale_entry->baseId)) {
|
if (!m_entries.contains(stale_entry->m_baseId)) {
|
||||||
qCritical() << "Cannot add entry with unknown base: " << stale_entry->baseId.toLocal8Bit();
|
qCritical() << "Cannot add entry with unknown base: " << stale_entry->m_baseId.toLocal8Bit();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stale_entry->stale) {
|
if (stale_entry->m_stale) {
|
||||||
qCritical() << "Cannot add stale entry: " << stale_entry->getFullPath().toLocal8Bit();
|
qCritical() << "Cannot add stale entry: " << stale_entry->getFullPath().toLocal8Bit();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_entries[stale_entry->baseId].entry_list[stale_entry->relativePath] = stale_entry;
|
m_entries[stale_entry->m_baseId].entry_list[stale_entry->m_relativePath] = stale_entry;
|
||||||
SaveEventually();
|
SaveEventually();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -157,7 +157,7 @@ auto HttpMetaCache::evictEntry(MetaEntryPtr entry) -> bool
|
|||||||
if (!entry)
|
if (!entry)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
entry->stale = true;
|
entry->m_stale = true;
|
||||||
SaveEventually();
|
SaveEventually();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -169,7 +169,7 @@ void HttpMetaCache::evictAll()
|
|||||||
qDebug() << "Evicting base" << base;
|
qDebug() << "Evicting base" << base;
|
||||||
for (MetaEntryPtr entry : map.entry_list) {
|
for (MetaEntryPtr entry : map.entry_list) {
|
||||||
if (!evictEntry(entry))
|
if (!evictEntry(entry))
|
||||||
qWarning() << "Unexpected missing cache entry" << entry->basePath;
|
qWarning() << "Unexpected missing cache entry" << entry->m_basePath;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -177,10 +177,10 @@ void HttpMetaCache::evictAll()
|
|||||||
auto HttpMetaCache::staleEntry(QString base, QString resource_path) -> MetaEntryPtr
|
auto HttpMetaCache::staleEntry(QString base, QString resource_path) -> MetaEntryPtr
|
||||||
{
|
{
|
||||||
auto foo = new MetaEntry();
|
auto foo = new MetaEntry();
|
||||||
foo->baseId = base;
|
foo->m_baseId = base;
|
||||||
foo->basePath = getBasePath(base);
|
foo->m_basePath = getBasePath(base);
|
||||||
foo->relativePath = resource_path;
|
foo->m_relativePath = resource_path;
|
||||||
foo->stale = true;
|
foo->m_stale = true;
|
||||||
|
|
||||||
return MetaEntryPtr(foo);
|
return MetaEntryPtr(foo);
|
||||||
}
|
}
|
||||||
@ -235,23 +235,23 @@ void HttpMetaCache::Load()
|
|||||||
auto& entrymap = m_entries[base];
|
auto& entrymap = m_entries[base];
|
||||||
|
|
||||||
auto foo = new MetaEntry();
|
auto foo = new MetaEntry();
|
||||||
foo->baseId = base;
|
foo->m_baseId = base;
|
||||||
foo->relativePath = Json::ensureString(element_obj, "path");
|
foo->m_relativePath = Json::ensureString(element_obj, "path");
|
||||||
foo->md5sum = Json::ensureString(element_obj, "md5sum");
|
foo->m_md5sum = Json::ensureString(element_obj, "md5sum");
|
||||||
foo->etag = Json::ensureString(element_obj, "etag");
|
foo->m_etag = Json::ensureString(element_obj, "etag");
|
||||||
foo->local_changed_timestamp = Json::ensureDouble(element_obj, "last_changed_timestamp");
|
foo->m_local_changed_timestamp = Json::ensureDouble(element_obj, "last_changed_timestamp");
|
||||||
foo->remote_changed_timestamp = Json::ensureString(element_obj, "remote_changed_timestamp");
|
foo->m_remote_changed_timestamp = Json::ensureString(element_obj, "remote_changed_timestamp");
|
||||||
|
|
||||||
foo->makeEternal(Json::ensureBoolean(element_obj, (const QString)QStringLiteral("eternal"), false));
|
foo->makeEternal(Json::ensureBoolean(element_obj, (const QString)QStringLiteral("eternal"), false));
|
||||||
if (!foo->isEternal()) {
|
if (!foo->isEternal()) {
|
||||||
foo->current_age = Json::ensureDouble(element_obj, "current_age");
|
foo->m_current_age = Json::ensureDouble(element_obj, "current_age");
|
||||||
foo->max_age = Json::ensureDouble(element_obj, "max_age");
|
foo->m_max_age = Json::ensureDouble(element_obj, "max_age");
|
||||||
}
|
}
|
||||||
|
|
||||||
// presumed innocent until closer examination
|
// presumed innocent until closer examination
|
||||||
foo->stale = false;
|
foo->m_stale = false;
|
||||||
|
|
||||||
entrymap.entry_list[foo->relativePath] = MetaEntryPtr(foo);
|
entrymap.entry_list[foo->m_relativePath] = MetaEntryPtr(foo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -276,23 +276,23 @@ void HttpMetaCache::SaveNow()
|
|||||||
for (auto group : m_entries) {
|
for (auto group : m_entries) {
|
||||||
for (auto entry : group.entry_list) {
|
for (auto entry : group.entry_list) {
|
||||||
// do not save stale entries. they are dead.
|
// do not save stale entries. they are dead.
|
||||||
if (entry->stale) {
|
if (entry->m_stale) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
QJsonObject entryObj;
|
QJsonObject entryObj;
|
||||||
Json::writeString(entryObj, "base", entry->baseId);
|
Json::writeString(entryObj, "base", entry->m_baseId);
|
||||||
Json::writeString(entryObj, "path", entry->relativePath);
|
Json::writeString(entryObj, "path", entry->m_relativePath);
|
||||||
Json::writeString(entryObj, "md5sum", entry->md5sum);
|
Json::writeString(entryObj, "md5sum", entry->m_md5sum);
|
||||||
Json::writeString(entryObj, "etag", entry->etag);
|
Json::writeString(entryObj, "etag", entry->m_etag);
|
||||||
entryObj.insert("last_changed_timestamp", QJsonValue(double(entry->local_changed_timestamp)));
|
entryObj.insert("last_changed_timestamp", QJsonValue(double(entry->m_local_changed_timestamp)));
|
||||||
if (!entry->remote_changed_timestamp.isEmpty())
|
if (!entry->m_remote_changed_timestamp.isEmpty())
|
||||||
entryObj.insert("remote_changed_timestamp", QJsonValue(entry->remote_changed_timestamp));
|
entryObj.insert("remote_changed_timestamp", QJsonValue(entry->m_remote_changed_timestamp));
|
||||||
if (entry->isEternal()) {
|
if (entry->isEternal()) {
|
||||||
entryObj.insert("eternal", true);
|
entryObj.insert("eternal", true);
|
||||||
} else {
|
} else {
|
||||||
entryObj.insert("current_age", QJsonValue(double(entry->current_age)));
|
entryObj.insert("current_age", QJsonValue(double(entry->m_current_age)));
|
||||||
entryObj.insert("max_age", QJsonValue(double(entry->max_age)));
|
entryObj.insert("max_age", QJsonValue(double(entry->m_max_age)));
|
||||||
}
|
}
|
||||||
entriesArr.append(entryObj);
|
entriesArr.append(entryObj);
|
||||||
}
|
}
|
||||||
|
@ -49,47 +49,47 @@ class MetaEntry {
|
|||||||
MetaEntry() = default;
|
MetaEntry() = default;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
auto isStale() -> bool { return stale; }
|
auto isStale() -> bool { return m_stale; }
|
||||||
void setStale(bool stale) { this->stale = stale; }
|
void setStale(bool stale) { m_stale = stale; }
|
||||||
|
|
||||||
auto getFullPath() -> QString;
|
auto getFullPath() -> QString;
|
||||||
|
|
||||||
auto getRemoteChangedTimestamp() -> QString { return remote_changed_timestamp; }
|
auto getRemoteChangedTimestamp() -> QString { return m_remote_changed_timestamp; }
|
||||||
void setRemoteChangedTimestamp(QString remote_changed_timestamp) { this->remote_changed_timestamp = remote_changed_timestamp; }
|
void setRemoteChangedTimestamp(QString remote_changed_timestamp) { m_remote_changed_timestamp = remote_changed_timestamp; }
|
||||||
void setLocalChangedTimestamp(qint64 timestamp) { local_changed_timestamp = timestamp; }
|
void setLocalChangedTimestamp(qint64 timestamp) { m_local_changed_timestamp = timestamp; }
|
||||||
|
|
||||||
auto getETag() -> QString { return etag; }
|
auto getETag() -> QString { return m_etag; }
|
||||||
void setETag(QString etag) { this->etag = etag; }
|
void setETag(QString etag) { m_etag = etag; }
|
||||||
|
|
||||||
auto getMD5Sum() -> QString { return md5sum; }
|
auto getMD5Sum() -> QString { return m_md5sum; }
|
||||||
void setMD5Sum(QString md5sum) { this->md5sum = md5sum; }
|
void setMD5Sum(QString md5sum) { m_md5sum = md5sum; }
|
||||||
|
|
||||||
/* Whether the entry expires after some time (false) or not (true). */
|
/* Whether the entry expires after some time (false) or not (true). */
|
||||||
void makeEternal(bool eternal) { is_eternal = eternal; }
|
void makeEternal(bool eternal) { m_is_eternal = eternal; }
|
||||||
[[nodiscard]] bool isEternal() const { return is_eternal; }
|
[[nodiscard]] bool isEternal() const { return m_is_eternal; }
|
||||||
|
|
||||||
auto getCurrentAge() -> qint64 { return current_age; }
|
auto getCurrentAge() -> qint64 { return m_current_age; }
|
||||||
void setCurrentAge(qint64 age) { current_age = age; }
|
void setCurrentAge(qint64 age) { m_current_age = age; }
|
||||||
|
|
||||||
auto getMaximumAge() -> qint64 { return max_age; }
|
auto getMaximumAge() -> qint64 { return m_max_age; }
|
||||||
void setMaximumAge(qint64 age) { max_age = age; }
|
void setMaximumAge(qint64 age) { m_max_age = age; }
|
||||||
|
|
||||||
bool isExpired(qint64 offset) { return !is_eternal && (current_age >= max_age - offset); };
|
bool isExpired(qint64 offset) { return !m_is_eternal && (m_current_age >= m_max_age - offset); };
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QString baseId;
|
QString m_baseId;
|
||||||
QString basePath;
|
QString m_basePath;
|
||||||
QString relativePath;
|
QString m_relativePath;
|
||||||
QString md5sum;
|
QString m_md5sum;
|
||||||
QString etag;
|
QString m_etag;
|
||||||
|
|
||||||
qint64 local_changed_timestamp = 0;
|
qint64 m_local_changed_timestamp = 0;
|
||||||
QString remote_changed_timestamp; // QString for now, RFC 2822 encoded time
|
QString m_remote_changed_timestamp; // QString for now, RFC 2822 encoded time
|
||||||
qint64 current_age = 0;
|
qint64 m_current_age = 0;
|
||||||
qint64 max_age = 0;
|
qint64 m_max_age = 0;
|
||||||
bool is_eternal = false;
|
bool m_is_eternal = false;
|
||||||
|
|
||||||
bool stale = true;
|
bool m_stale = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
using MetaEntryPtr = std::shared_ptr<MetaEntry>;
|
using MetaEntryPtr = std::shared_ptr<MetaEntry>;
|
||||||
|
@ -62,6 +62,7 @@
|
|||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
#include <QMenuBar>
|
#include <QMenuBar>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
|
#include <QFileDialog>
|
||||||
#include <QInputDialog>
|
#include <QInputDialog>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QToolButton>
|
#include <QToolButton>
|
||||||
@ -255,6 +256,9 @@ public:
|
|||||||
QMenu * helpMenu = nullptr;
|
QMenu * helpMenu = nullptr;
|
||||||
TranslatedToolButton helpMenuButton;
|
TranslatedToolButton helpMenuButton;
|
||||||
TranslatedAction actionClearMetadata;
|
TranslatedAction actionClearMetadata;
|
||||||
|
#ifdef Q_OS_MAC
|
||||||
|
TranslatedAction actionAddToPATH;
|
||||||
|
#endif
|
||||||
TranslatedAction actionReportBug;
|
TranslatedAction actionReportBug;
|
||||||
TranslatedAction actionDISCORD;
|
TranslatedAction actionDISCORD;
|
||||||
TranslatedAction actionMATRIX;
|
TranslatedAction actionMATRIX;
|
||||||
@ -352,6 +356,14 @@ public:
|
|||||||
actionClearMetadata.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Clear cached metadata"));
|
actionClearMetadata.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Clear cached metadata"));
|
||||||
all_actions.append(&actionClearMetadata);
|
all_actions.append(&actionClearMetadata);
|
||||||
|
|
||||||
|
#ifdef Q_OS_MAC
|
||||||
|
actionAddToPATH = TranslatedAction(MainWindow);
|
||||||
|
actionAddToPATH->setObjectName(QStringLiteral("actionAddToPATH"));
|
||||||
|
actionAddToPATH.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Install to &PATH"));
|
||||||
|
actionAddToPATH.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Install a prismlauncher symlink to /usr/local/bin"));
|
||||||
|
all_actions.append(&actionAddToPATH);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!BuildConfig.BUG_TRACKER_URL.isEmpty()) {
|
if (!BuildConfig.BUG_TRACKER_URL.isEmpty()) {
|
||||||
actionReportBug = TranslatedAction(MainWindow);
|
actionReportBug = TranslatedAction(MainWindow);
|
||||||
actionReportBug->setObjectName(QStringLiteral("actionReportBug"));
|
actionReportBug->setObjectName(QStringLiteral("actionReportBug"));
|
||||||
@ -457,6 +469,10 @@ public:
|
|||||||
|
|
||||||
helpMenu->addAction(actionClearMetadata);
|
helpMenu->addAction(actionClearMetadata);
|
||||||
|
|
||||||
|
#ifdef Q_OS_MAC
|
||||||
|
helpMenu->addAction(actionAddToPATH);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!BuildConfig.BUG_TRACKER_URL.isEmpty()) {
|
if (!BuildConfig.BUG_TRACKER_URL.isEmpty()) {
|
||||||
helpMenu->addAction(actionReportBug);
|
helpMenu->addAction(actionReportBug);
|
||||||
}
|
}
|
||||||
@ -544,6 +560,9 @@ public:
|
|||||||
helpMenu = menuBar->addMenu(tr("&Help"));
|
helpMenu = menuBar->addMenu(tr("&Help"));
|
||||||
helpMenu->setSeparatorsCollapsible(false);
|
helpMenu->setSeparatorsCollapsible(false);
|
||||||
helpMenu->addAction(actionClearMetadata);
|
helpMenu->addAction(actionClearMetadata);
|
||||||
|
#ifdef Q_OS_MAC
|
||||||
|
helpMenu->addAction(actionAddToPATH);
|
||||||
|
#endif
|
||||||
helpMenu->addSeparator();
|
helpMenu->addSeparator();
|
||||||
helpMenu->addAction(actionAbout);
|
helpMenu->addAction(actionAbout);
|
||||||
helpMenu->addAction(actionOpenWiki);
|
helpMenu->addAction(actionOpenWiki);
|
||||||
@ -1943,6 +1962,29 @@ void MainWindow::on_actionClearMetadata_triggered()
|
|||||||
APPLICATION->metacache()->SaveNow();
|
APPLICATION->metacache()->SaveNow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef Q_OS_MAC
|
||||||
|
void MainWindow::on_actionAddToPATH_triggered()
|
||||||
|
{
|
||||||
|
auto binaryPath = APPLICATION->applicationFilePath();
|
||||||
|
auto targetPath = QString("/usr/local/bin/%1").arg(BuildConfig.LAUNCHER_APP_BINARY_NAME);
|
||||||
|
qDebug() << "Symlinking" << binaryPath << "to" << targetPath;
|
||||||
|
|
||||||
|
QStringList args;
|
||||||
|
args << "-e";
|
||||||
|
args << QString("do shell script \"mkdir -p /usr/local/bin && ln -sf '%1' '%2'\" with administrator privileges")
|
||||||
|
.arg(binaryPath, targetPath);
|
||||||
|
auto outcome = QProcess::execute("/usr/bin/osascript", args);
|
||||||
|
if (!outcome) {
|
||||||
|
QMessageBox::information(this, tr("Successfully added %1 to PATH").arg(BuildConfig.LAUNCHER_DISPLAYNAME),
|
||||||
|
tr("%1 was successfully added to your PATH. You can now start it by running `%2`.")
|
||||||
|
.arg(BuildConfig.LAUNCHER_DISPLAYNAME, BuildConfig.LAUNCHER_APP_BINARY_NAME));
|
||||||
|
} else {
|
||||||
|
QMessageBox::critical(this, tr("Failed to add %1 to PATH").arg(BuildConfig.LAUNCHER_DISPLAYNAME),
|
||||||
|
tr("An error occurred while trying to add %1 to PATH").arg(BuildConfig.LAUNCHER_DISPLAYNAME));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void MainWindow::on_actionOpenWiki_triggered()
|
void MainWindow::on_actionOpenWiki_triggered()
|
||||||
{
|
{
|
||||||
DesktopServices::openUrl(QUrl(BuildConfig.HELP_URL.arg("")));
|
DesktopServices::openUrl(QUrl(BuildConfig.HELP_URL.arg("")));
|
||||||
|
@ -128,6 +128,10 @@ private slots:
|
|||||||
|
|
||||||
void on_actionClearMetadata_triggered();
|
void on_actionClearMetadata_triggered();
|
||||||
|
|
||||||
|
#ifdef Q_OS_MAC
|
||||||
|
void on_actionAddToPATH_triggered();
|
||||||
|
#endif
|
||||||
|
|
||||||
void on_actionOpenWiki_triggered();
|
void on_actionOpenWiki_triggered();
|
||||||
|
|
||||||
void on_actionMoreNews_triggered();
|
void on_actionMoreNews_triggered();
|
||||||
|
@ -27,11 +27,7 @@
|
|||||||
<item row="4" column="1" colspan="3">
|
<item row="4" column="1" colspan="3">
|
||||||
<layout class="QGridLayout" name="gridLayout_2">
|
<layout class="QGridLayout" name="gridLayout_2">
|
||||||
<item row="0" column="1">
|
<item row="0" column="1">
|
||||||
<widget class="QLineEdit" name="filterEdit">
|
<widget class="QLineEdit" name="filterEdit"/>
|
||||||
<property name="clearButtonEnabled">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
<widget class="QLabel" name="filterLabel">
|
<widget class="QLabel" name="filterLabel">
|
||||||
|
@ -400,11 +400,11 @@ public:
|
|||||||
|
|
||||||
virtual int rowCount(const QModelIndex &parent = QModelIndex()) const override
|
virtual int rowCount(const QModelIndex &parent = QModelIndex()) const override
|
||||||
{
|
{
|
||||||
return m_servers.size();
|
return parent.isValid() ? 0 : m_servers.size();
|
||||||
}
|
}
|
||||||
int columnCount(const QModelIndex & parent) const override
|
int columnCount(const QModelIndex & parent) const override
|
||||||
{
|
{
|
||||||
return COLUMN_COUNT;
|
return parent.isValid() ? 0 : COLUMN_COUNT;
|
||||||
}
|
}
|
||||||
|
|
||||||
Server * at(int index)
|
Server * at(int index)
|
||||||
|
@ -48,11 +48,7 @@
|
|||||||
<item>
|
<item>
|
||||||
<layout class="QGridLayout" name="gridLayout_2">
|
<layout class="QGridLayout" name="gridLayout_2">
|
||||||
<item row="0" column="1">
|
<item row="0" column="1">
|
||||||
<widget class="QLineEdit" name="filterEdit">
|
<widget class="QLineEdit" name="filterEdit"/>
|
||||||
<property name="clearButtonEnabled">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
<widget class="QLabel" name="filterLabel">
|
<widget class="QLabel" name="filterLabel">
|
||||||
|
@ -20,8 +20,8 @@ class ListModel : public QAbstractListModel {
|
|||||||
ListModel(ModPage* parent);
|
ListModel(ModPage* parent);
|
||||||
~ListModel() override;
|
~ListModel() override;
|
||||||
|
|
||||||
inline auto rowCount(const QModelIndex& parent) const -> int override { return modpacks.size(); };
|
inline auto rowCount(const QModelIndex& parent) const -> int override { return parent.isValid() ? 0 : modpacks.size(); };
|
||||||
inline auto columnCount(const QModelIndex& parent) const -> int override { return 1; };
|
inline auto columnCount(const QModelIndex& parent) const -> int override { return parent.isValid() ? 0 : 1; };
|
||||||
inline auto flags(const QModelIndex& index) const -> Qt::ItemFlags override { return QAbstractListModel::flags(index); };
|
inline auto flags(const QModelIndex& index) const -> Qt::ItemFlags override { return QAbstractListModel::flags(index); };
|
||||||
|
|
||||||
auto debugName() const -> QString;
|
auto debugName() const -> QString;
|
||||||
@ -41,12 +41,12 @@ class ListModel : public QAbstractListModel {
|
|||||||
void requestModVersions(const ModPlatform::IndexedPack& current, QModelIndex index);
|
void requestModVersions(const ModPlatform::IndexedPack& current, QModelIndex index);
|
||||||
|
|
||||||
virtual void loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj) = 0;
|
virtual void loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj) = 0;
|
||||||
virtual void loadExtraPackInfo(ModPlatform::IndexedPack& m, QJsonObject& obj) {};
|
virtual void loadExtraPackInfo(ModPlatform::IndexedPack& m, QJsonObject& obj) = 0;
|
||||||
virtual void loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr) = 0;
|
virtual void loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr) = 0;
|
||||||
|
|
||||||
void getLogo(const QString& logo, const QString& logoUrl, LogoCallback callback);
|
void getLogo(const QString& logo, const QString& logoUrl, LogoCallback callback);
|
||||||
|
|
||||||
inline auto canFetchMore(const QModelIndex& parent) const -> bool override { return searchState == CanPossiblyFetchMore; };
|
inline auto canFetchMore(const QModelIndex& parent) const -> bool override { return parent.isValid() ? false : searchState == CanPossiblyFetchMore; };
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void searchRequestFinished(QJsonDocument& doc);
|
void searchRequestFinished(QJsonDocument& doc);
|
||||||
|
@ -262,7 +262,7 @@ void ModPage::openUrl(const QUrl& url)
|
|||||||
|
|
||||||
const QString address = url.host() + url.path();
|
const QString address = url.host() + url.path();
|
||||||
QRegularExpressionMatch match;
|
QRegularExpressionMatch match;
|
||||||
const char* page;
|
QString page;
|
||||||
|
|
||||||
match = modrinth.match(address);
|
match = modrinth.match(address);
|
||||||
if (match.hasMatch())
|
if (match.hasMatch())
|
||||||
@ -276,7 +276,7 @@ void ModPage::openUrl(const QUrl& url)
|
|||||||
page = "curseforge";
|
page = "curseforge";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (match.hasMatch()) {
|
if (!page.isNull()) {
|
||||||
const QString slug = match.captured(1);
|
const QString slug = match.captured(1);
|
||||||
|
|
||||||
// ensure the user isn't opening the same mod
|
// ensure the user isn't opening the same mod
|
||||||
|
@ -32,12 +32,12 @@ ListModel::~ListModel()
|
|||||||
|
|
||||||
int ListModel::rowCount(const QModelIndex &parent) const
|
int ListModel::rowCount(const QModelIndex &parent) const
|
||||||
{
|
{
|
||||||
return modpacks.size();
|
return parent.isValid() ? 0 : modpacks.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
int ListModel::columnCount(const QModelIndex &parent) const
|
int ListModel::columnCount(const QModelIndex &parent) const
|
||||||
{
|
{
|
||||||
return 1;
|
return parent.isValid() ? 0 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant ListModel::data(const QModelIndex &index, int role) const
|
QVariant ListModel::data(const QModelIndex &index, int role) const
|
||||||
|
@ -75,12 +75,12 @@ QVector<QString> AtlOptionalModListModel::getResult() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int AtlOptionalModListModel::rowCount(const QModelIndex &parent) const {
|
int AtlOptionalModListModel::rowCount(const QModelIndex &parent) const {
|
||||||
return m_mods.size();
|
return parent.isValid() ? 0 : m_mods.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
int AtlOptionalModListModel::columnCount(const QModelIndex &parent) const {
|
int AtlOptionalModListModel::columnCount(const QModelIndex &parent) const {
|
||||||
// Enabled, Name, Description
|
// Enabled, Name, Description
|
||||||
return 3;
|
return parent.isValid() ? 0 : 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant AtlOptionalModListModel::data(const QModelIndex &index, int role) const {
|
QVariant AtlOptionalModListModel::data(const QModelIndex &index, int role) const {
|
||||||
|
@ -15,12 +15,12 @@ ListModel::~ListModel() {}
|
|||||||
|
|
||||||
int ListModel::rowCount(const QModelIndex& parent) const
|
int ListModel::rowCount(const QModelIndex& parent) const
|
||||||
{
|
{
|
||||||
return modpacks.size();
|
return parent.isValid() ? 0 : modpacks.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
int ListModel::columnCount(const QModelIndex& parent) const
|
int ListModel::columnCount(const QModelIndex& parent) const
|
||||||
{
|
{
|
||||||
return 1;
|
return parent.isValid() ? 0 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant ListModel::data(const QModelIndex& index, int role) const
|
QVariant ListModel::data(const QModelIndex& index, int role) const
|
||||||
|
@ -34,12 +34,12 @@ ListModel::~ListModel()
|
|||||||
|
|
||||||
int ListModel::rowCount(const QModelIndex &parent) const
|
int ListModel::rowCount(const QModelIndex &parent) const
|
||||||
{
|
{
|
||||||
return modpacks.size();
|
return parent.isValid() ? 0 : modpacks.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
int ListModel::columnCount(const QModelIndex &parent) const
|
int ListModel::columnCount(const QModelIndex &parent) const
|
||||||
{
|
{
|
||||||
return 1;
|
return parent.isValid() ? 0 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant ListModel::data(const QModelIndex &index, int role) const
|
QVariant ListModel::data(const QModelIndex &index, int role) const
|
||||||
|
@ -125,12 +125,12 @@ QString ListModel::translatePackType(PackType type) const
|
|||||||
|
|
||||||
int ListModel::rowCount(const QModelIndex &parent) const
|
int ListModel::rowCount(const QModelIndex &parent) const
|
||||||
{
|
{
|
||||||
return modpacks.size();
|
return parent.isValid() ? 0 : modpacks.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
int ListModel::columnCount(const QModelIndex &parent) const
|
int ListModel::columnCount(const QModelIndex &parent) const
|
||||||
{
|
{
|
||||||
return 1;
|
return parent.isValid() ? 0 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant ListModel::data(const QModelIndex &index, int role) const
|
QVariant ListModel::data(const QModelIndex &index, int role) const
|
||||||
|
@ -55,8 +55,8 @@ class ModpackListModel : public QAbstractListModel {
|
|||||||
ModpackListModel(ModrinthPage* parent);
|
ModpackListModel(ModrinthPage* parent);
|
||||||
~ModpackListModel() override = default;
|
~ModpackListModel() override = default;
|
||||||
|
|
||||||
inline auto rowCount(const QModelIndex& parent) const -> int override { return modpacks.size(); };
|
inline auto rowCount(const QModelIndex& parent) const -> int override { return parent.isValid() ? 0 : modpacks.size(); };
|
||||||
inline auto columnCount(const QModelIndex& parent) const -> int override { return 1; };
|
inline auto columnCount(const QModelIndex& parent) const -> int override { return parent.isValid() ? 0 : 1; };
|
||||||
inline auto flags(const QModelIndex& index) const -> Qt::ItemFlags override { return QAbstractListModel::flags(index); };
|
inline auto flags(const QModelIndex& index) const -> Qt::ItemFlags override { return QAbstractListModel::flags(index); };
|
||||||
|
|
||||||
auto debugName() const -> QString;
|
auto debugName() const -> QString;
|
||||||
@ -74,7 +74,7 @@ class ModpackListModel : public QAbstractListModel {
|
|||||||
|
|
||||||
void getLogo(const QString& logo, const QString& logoUrl, LogoCallback callback);
|
void getLogo(const QString& logo, const QString& logoUrl, LogoCallback callback);
|
||||||
|
|
||||||
inline auto canFetchMore(const QModelIndex& parent) const -> bool override { return searchState == CanPossiblyFetchMore; };
|
inline auto canFetchMore(const QModelIndex& parent) const -> bool override { return parent.isValid() ? false : searchState == CanPossiblyFetchMore; };
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void searchRequestFinished(QJsonDocument& doc_all);
|
void searchRequestFinished(QJsonDocument& doc_all);
|
||||||
|
@ -80,14 +80,14 @@ QVariant Technic::ListModel::data(const QModelIndex& index, int role) const
|
|||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
int Technic::ListModel::columnCount(const QModelIndex&) const
|
int Technic::ListModel::columnCount(const QModelIndex& parent) const
|
||||||
{
|
{
|
||||||
return 1;
|
return parent.isValid() ? 0 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Technic::ListModel::rowCount(const QModelIndex&) const
|
int Technic::ListModel::rowCount(const QModelIndex& parent) const
|
||||||
{
|
{
|
||||||
return modpacks.size();
|
return parent.isValid() ? 0 : modpacks.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Technic::ListModel::searchWithTerm(const QString& term)
|
void Technic::ListModel::searchWithTerm(const QString& term)
|
||||||
|
Loading…
Reference in New Issue
Block a user