diff options
Diffstat (limited to 'launcher/minecraft/mod')
-rw-r--r-- | launcher/minecraft/mod/ModFolderModel.cpp | 20 | ||||
-rw-r--r-- | launcher/minecraft/mod/Resource.cpp | 20 | ||||
-rw-r--r-- | launcher/minecraft/mod/Resource.h | 13 | ||||
-rw-r--r-- | launcher/minecraft/mod/ResourceFolderModel.cpp | 26 | ||||
-rw-r--r-- | launcher/minecraft/mod/ResourceFolderModel.h | 2 | ||||
-rw-r--r-- | launcher/minecraft/mod/ResourcePackFolderModel.cpp | 20 |
6 files changed, 101 insertions, 0 deletions
diff --git a/launcher/minecraft/mod/ModFolderModel.cpp b/launcher/minecraft/mod/ModFolderModel.cpp index 3f31b93c..e2053f92 100644 --- a/launcher/minecraft/mod/ModFolderModel.cpp +++ b/launcher/minecraft/mod/ModFolderModel.cpp @@ -39,13 +39,17 @@ #include <FileSystem.h> #include <QDebug> #include <QFileSystemWatcher> +#include <QIcon> #include <QMimeData> #include <QString> +#include <QStyle> #include <QThreadPool> #include <QUrl> #include <QUuid> #include <algorithm> +#include "Application.h" + #include "minecraft/mod/tasks/LocalModParseTask.h" #include "minecraft/mod/tasks/ModFolderLoadTask.h" #include "modplatform/ModIndex.h" @@ -97,8 +101,24 @@ QVariant ModFolderModel::data(const QModelIndex &index, int role) const } case Qt::ToolTipRole: + if (column == NAME_COLUMN) { + if (at(row)->isSymLinkUnder(instDirPath())) { + return m_resources[row]->internal_id() + + tr("\nWarning: This resource is symbolicly linked from elsewhere. Editing it will also change the origonal") + + tr("\nCanonical Path: %1").arg(at(row)->fileinfo().canonicalFilePath()); + } + if (at(row)->isMoreThanOneHardLink()) { + return m_resources[row]->internal_id() + + tr("\nWarning: This resource is hard linked elsewhere. Editing it will also change the origonal"); + } + } return m_resources[row]->internal_id(); + case Qt::DecorationRole: { + if (column == NAME_COLUMN && (at(row)->isSymLinkUnder(instDirPath()) || at(row)->isMoreThanOneHardLink())) + return APPLICATION->getThemedIcon("status-yellow"); + return {}; + } case Qt::CheckStateRole: switch (column) { diff --git a/launcher/minecraft/mod/Resource.cpp b/launcher/minecraft/mod/Resource.cpp index 0d35d755..a0b8a4bb 100644 --- a/launcher/minecraft/mod/Resource.cpp +++ b/launcher/minecraft/mod/Resource.cpp @@ -1,6 +1,8 @@ #include "Resource.h" + #include <QRegularExpression> +#include <QFileInfo> #include "FileSystem.h" @@ -152,3 +154,21 @@ bool Resource::destroy() return FS::deletePath(m_file_info.filePath()); } + +bool Resource::isSymLinkUnder(const QString& instPath) const +{ + if (isSymLink()) + return true; + + auto instDir = QDir(instPath); + + auto relAbsPath = instDir.relativeFilePath(m_file_info.absoluteFilePath()); + auto relCanonPath = instDir.relativeFilePath(m_file_info.canonicalFilePath()); + + return relAbsPath != relCanonPath; +} + +bool Resource::isMoreThanOneHardLink() const +{ + return FS::hardLinkCount(m_file_info.absoluteFilePath()) > 1; +} diff --git a/launcher/minecraft/mod/Resource.h b/launcher/minecraft/mod/Resource.h index 0c37f3a3..a5e9ae91 100644 --- a/launcher/minecraft/mod/Resource.h +++ b/launcher/minecraft/mod/Resource.h @@ -94,6 +94,19 @@ class Resource : public QObject { // Delete all files of this resource. bool destroy(); + [[nodiscard]] auto isSymLink() const -> bool { return m_file_info.isSymLink(); } + + /** + * @brief Take a instance path, checks if the file pointed to by the resource is a symlink or under a symlink in that instance + * + * @param instPath path to an instance directory + * @return true + * @return false + */ + [[nodiscard]] bool isSymLinkUnder(const QString& instPath) const; + + [[nodiscard]] bool isMoreThanOneHardLink() const; + protected: /* The file corresponding to this resource. */ QFileInfo m_file_info; diff --git a/launcher/minecraft/mod/ResourceFolderModel.cpp b/launcher/minecraft/mod/ResourceFolderModel.cpp index f2a77c12..d1748c1c 100644 --- a/launcher/minecraft/mod/ResourceFolderModel.cpp +++ b/launcher/minecraft/mod/ResourceFolderModel.cpp @@ -2,10 +2,14 @@ #include <QCoreApplication> #include <QDebug> +#include <QFileInfo> +#include <QIcon> #include <QMimeData> +#include <QStyle> #include <QThreadPool> #include <QUrl> +#include "Application.h" #include "FileSystem.h" #include "minecraft/mod/tasks/BasicFolderLoadTask.h" @@ -417,7 +421,25 @@ QVariant ResourceFolderModel::data(const QModelIndex& index, int role) const return {}; } case Qt::ToolTipRole: + if (column == NAME_COLUMN) { + if (at(row).isSymLinkUnder(instDirPath())) { + return m_resources[row]->internal_id() + + tr("\nWarning: This resource is symbolicly linked from elsewhere. Editing it will also change the origonal") + + tr("\nCanonical Path: %1").arg(at(row).fileinfo().canonicalFilePath());; + } + if (at(row).isMoreThanOneHardLink()) { + return m_resources[row]->internal_id() + + tr("\nWarning: This resource is hard linked elsewhere. Editing it will also change the origonal"); + } + } + return m_resources[row]->internal_id(); + case Qt::DecorationRole: { + if (column == NAME_COLUMN && (at(row).isSymLinkUnder(instDirPath()) || at(row).isMoreThanOneHardLink())) + return APPLICATION->getThemedIcon("status-yellow"); + + return {}; + } case Qt::CheckStateRole: switch (column) { case ACTIVE_COLUMN: @@ -531,3 +553,7 @@ void ResourceFolderModel::enableInteraction(bool enabled) return (compare_result.first < 0); return (compare_result.first > 0); } + +QString ResourceFolderModel::instDirPath() const { + return QFileInfo(m_dir.filePath("../..")).absoluteFilePath(); +} diff --git a/launcher/minecraft/mod/ResourceFolderModel.h b/launcher/minecraft/mod/ResourceFolderModel.h index 3bd78870..f840b2de 100644 --- a/launcher/minecraft/mod/ResourceFolderModel.h +++ b/launcher/minecraft/mod/ResourceFolderModel.h @@ -125,6 +125,8 @@ class ResourceFolderModel : public QAbstractListModel { [[nodiscard]] bool lessThan(const QModelIndex& source_left, const QModelIndex& source_right) const override; }; + QString instDirPath() const; + public slots: void enableInteraction(bool enabled); void disableInteraction(bool disabled) { enableInteraction(!disabled); } diff --git a/launcher/minecraft/mod/ResourcePackFolderModel.cpp b/launcher/minecraft/mod/ResourcePackFolderModel.cpp index da4bd091..56584a34 100644 --- a/launcher/minecraft/mod/ResourcePackFolderModel.cpp +++ b/launcher/minecraft/mod/ResourcePackFolderModel.cpp @@ -36,6 +36,10 @@ #include "ResourcePackFolderModel.h" +#include <QIcon> +#include <QStyle> + +#include "Application.h" #include "Version.h" #include "minecraft/mod/tasks/BasicFolderLoadTask.h" @@ -78,12 +82,28 @@ QVariant ResourcePackFolderModel::data(const QModelIndex& index, int role) const default: return {}; } + case Qt::DecorationRole: { + if (column == NAME_COLUMN && (at(row)->isSymLinkUnder(instDirPath()) || at(row)->isMoreThanOneHardLink())) + return APPLICATION->getThemedIcon("status-yellow"); + return {}; + } case Qt::ToolTipRole: { if (column == PackFormatColumn) { //: The string being explained by this is in the format: ID (Lower version - Upper version) return tr("The resource pack format ID, as well as the Minecraft versions it was designed for."); } + if (column == NAME_COLUMN) { + if (at(row)->isSymLinkUnder(instDirPath())) { + return m_resources[row]->internal_id() + + tr("\nWarning: This resource is symbolicly linked from elsewhere. Editing it will also change the origonal") + + tr("\nCanonical Path: %1").arg(at(row)->fileinfo().canonicalFilePath());; + } + if (at(row)->isMoreThanOneHardLink()) { + return m_resources[row]->internal_id() + + tr("\nWarning: This resource is hard linked elsewhere. Editing it will also change the origonal"); + } + } return m_resources[row]->internal_id(); } case Qt::CheckStateRole: |