diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 000000000..41f0604e4 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,9 @@ + diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b6400791d..ba8f9d38d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -30,12 +30,12 @@ jobs: - os: windows-2022 name: "Windows-Legacy" - msystem: mingw32 + msystem: clang32 qt_ver: 5 - os: windows-2022 name: "Windows" - msystem: mingw32 + msystem: clang64 qt_ver: 6 - os: macos-12 @@ -89,6 +89,7 @@ jobs: update: true install: >- git + mingw-w64-x86_64-binutils pacboy: >- toolchain:p cmake:p @@ -99,12 +100,11 @@ jobs: qt${{ matrix.qt_ver }}-imageformats:p quazip-qt${{ matrix.qt_ver }}:p ccache:p - nsis:p ${{ matrix.qt_ver == 6 && 'qt6-5compat:p' || '' }} - name: Setup ccache if: runner.os != 'Windows' && inputs.build_type == 'Debug' - uses: hendrikmuhs/ccache-action@v1.2.3 + uses: hendrikmuhs/ccache-action@v1.2.5 with: key: ${{ matrix.os }}-qt${{ matrix.qt_ver }} @@ -194,7 +194,7 @@ jobs: if: runner.os == 'Windows' shell: msys2 {0} run: | - cmake -S . -B ${{ env.BUILD_DIR }} -DCMAKE_INSTALL_PREFIX=${{ env.INSTALL_DIR }} -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} -DENABLE_LTO=ON -DLauncher_BUILD_PLATFORM=${{ matrix.name }} -DCMAKE_C_COMPILER_LAUNCHER=${{ env.CCACHE_VAR }} -DCMAKE_CXX_COMPILER_LAUNCHER=${{ env.CCACHE_VAR }} -DLauncher_QT_VERSION_MAJOR=${{ matrix.qt_ver }} -G Ninja + cmake -S . -B ${{ env.BUILD_DIR }} -DCMAKE_INSTALL_PREFIX=${{ env.INSTALL_DIR }} -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} -DENABLE_LTO=ON -DLauncher_BUILD_PLATFORM=${{ matrix.name }} -DCMAKE_C_COMPILER_LAUNCHER=${{ env.CCACHE_VAR }} -DCMAKE_CXX_COMPILER_LAUNCHER=${{ env.CCACHE_VAR }} -DLauncher_QT_VERSION_MAJOR=${{ matrix.qt_ver }} -DCMAKE_OBJDUMP=/mingw64/bin/objdump.exe -G Ninja - name: Configure CMake (Linux) if: runner.os == 'Linux' @@ -251,6 +251,7 @@ jobs: cd ${{ env.INSTALL_DIR }} chmod +x "PrismLauncher.app/Contents/MacOS/prismlauncher" sudo codesign --sign - --deep --force --entitlements "../program_info/App.entitlements" --options runtime "PrismLauncher.app/Contents/MacOS/prismlauncher" + mv "PrismLauncher.app" "Prism Launcher.app" tar -czf ../PrismLauncher.tar.gz * - name: Make Sparkle signature (macOS) @@ -280,7 +281,7 @@ jobs: cd ${{ env.INSTALL_DIR }} if [ "${{ matrix.qt_ver }}" == "5" ]; then - cp /mingw32/bin/libcrypto-1_1.dll /mingw32/bin/libssl-1_1.dll ./ + cp /clang32/bin/libcrypto-1_1.dll /clang32/bin/libssl-1_1.dll ./ fi - name: Package (Windows, portable) @@ -292,7 +293,6 @@ jobs: - name: Package (Windows, installer) if: runner.os == 'Windows' - shell: msys2 {0} run: | cd ${{ env.INSTALL_DIR }} makensis -NOCD "${{ github.workspace }}/${{ env.BUILD_DIR }}/program_info/win_install.nsi" diff --git a/.github/workflows/trigger_builds.yml b/.github/workflows/trigger_builds.yml index 55b4fdd4f..8adaa5e52 100644 --- a/.github/workflows/trigger_builds.yml +++ b/.github/workflows/trigger_builds.yml @@ -3,7 +3,7 @@ name: Build Application on: push: branches-ignore: - - 'stable' + - 'renovate/**' paths-ignore: - '**.md' - '**/LICENSE' diff --git a/CMakeLists.txt b/CMakeLists.txt index 310bc9a87..727562921 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,6 +34,11 @@ set(CMAKE_C_STANDARD 11) include(GenerateExportHeader) set(CMAKE_CXX_FLAGS "-Wall -pedantic -fstack-protector-strong --param=ssp-buffer-size=4 ${CMAKE_CXX_FLAGS}") +# ATL's packlist needs more than the default 1 Mib stack on windows +if(WIN32) + set(CMAKE_EXE_LINKER_FLAGS "-Wl,--stack,8388608 ${CMAKE_EXE_LINKER_FLAGS}") +endif() + # Fix build with Qt 5.13 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DQT_NO_DEPRECATED_WARNINGS=Y") @@ -222,14 +227,14 @@ if(UNIX AND APPLE) set(APPS "\${CMAKE_INSTALL_PREFIX}/${Launcher_Name}.app") # Mac bundle settings - set(MACOSX_BUNDLE_BUNDLE_NAME "${Launcher_Name}") - set(MACOSX_BUNDLE_INFO_STRING "${Launcher_Name}: A custom launcher for Minecraft that allows you to easily manage multiple installations of Minecraft at once.") + set(MACOSX_BUNDLE_BUNDLE_NAME "${Launcher_DisplayName}") + set(MACOSX_BUNDLE_INFO_STRING "${Launcher_DisplayName}: A custom launcher for Minecraft that allows you to easily manage multiple installations of Minecraft at once.") set(MACOSX_BUNDLE_GUI_IDENTIFIER "org.prismlauncher.${Launcher_Name}") set(MACOSX_BUNDLE_BUNDLE_VERSION "${Launcher_VERSION_NAME}") set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${Launcher_VERSION_NAME}") set(MACOSX_BUNDLE_LONG_VERSION_STRING "${Launcher_VERSION_NAME}") set(MACOSX_BUNDLE_ICON_FILE ${Launcher_Name}.icns) - set(MACOSX_BUNDLE_COPYRIGHT "Copyright 2021-2022 ${Launcher_Copyright}") + set(MACOSX_BUNDLE_COPYRIGHT "© 2022 ${Launcher_Copyright_Mac}") set(MACOSX_SPARKLE_UPDATE_PUBLIC_KEY "v55ZWWD6QlPoXGV6VLzOTZxZUggWeE51X8cRQyQh6vA=") set(MACOSX_SPARKLE_UPDATE_FEED_URL "https://prismlauncher.org/feed/appcast.xml") @@ -251,7 +256,7 @@ elseif(UNIX) set(BINARY_DEST_DIR "bin") set(LIBRARY_DEST_DIR "lib${LIB_SUFFIX}") - set(JARS_DEST_DIR "share/jars") + set(JARS_DEST_DIR "share/${Launcher_APP_BINARY_NAME}") # install as bundle with no dependencies included set(INSTALL_BUNDLE "nodeps") diff --git a/README.md b/README.md index d7df8e264..57f1e30a3 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,20 @@ -

+

Prism Launcher logo Prism Launcher logo

+ Prism Launcher is a custom launcher for Minecraft that allows you to easily manage multiple installations of Minecraft at once. This is a **fork** of the MultiMC Launcher and not endorsed by MultiMC. + ## Installation + + Packaging status + + - All downloads and instructions for Prism Launcher can be found [on our website](https://prismlauncher.org/download/). - Last build status can be found [here](https://github.com/PrismLauncher/PrismLauncher/actions). @@ -16,25 +22,24 @@ This is a **fork** of the MultiMC Launcher and not endorsed by MultiMC. There are development builds available [here](https://github.com/PrismLauncher/PrismLauncher/actions). These have debug information in the binaries, so their file sizes are relatively larger. -Portable builds are provided for on Linux, Windows, and macOS. +Portable builds are provided for Linux, Windows, and macOS. + +For Arch, Debian and Gentoo, respectively, you can use these packages to get compiled development versions: + +[![prismlauncher-git](https://img.shields.io/badge/aur-prismlauncher--git-blue?style=flat-square)](https://aur.archlinux.org/packages/prismlauncher-qt5-git/) [![prismlauncher-git](https://img.shields.io/badge/aur-prismlauncher--qt5--git-blue?style=flat-square)](https://aur.archlinux.org/packages/prismlauncher-git/) [![prismlauncher-git](https://img.shields.io/badge/mpr-prismlauncher--git-orange?style=flat-square)](https://mpr.makedeb.org/packages/prismlauncher-git) [![prismlauncher-9999](https://img.shields.io/badge/gentoo-prismlauncher--9999-purple?style=flat-square)](https://packages.gentoo.org/packages/games-action/prismlauncher) -For Debian and Arch, you can use these packages for the latest development versions: -[![prismlauncher-git](https://img.shields.io/badge/aur-prismlauncher--git-blue)](https://aur.archlinux.org/packages/prismlauncher-git/) -[![prismlauncher-git](https://img.shields.io/badge/mpr-prismlauncher--git-orange)](https://mpr.makedeb.org/packages/prismlauncher-git) ## Help & Support -Feel free to create an issue if you need help. However, you might find it easier to ask in the Discord server. +Feel free to create an issue if you need help. +#### Join our Discord server: [![Prism Launcher Discord server](https://discordapp.com/api/guilds/1031648380885147709/widget.png?style=banner3)](https://discord.gg/prismlauncher) -We will also soon be opening up our Matrix channels. -You can already join our Matrix space: +#### Join our Matrix space: +[![PrismLauncher Space](https://img.shields.io/matrix/prismlauncher:matrix.org?style=for-the-badge)](https://matrix.to/#/#prismlauncher:matrix.org) -[![PrismLauncher Space](https://img.shields.io/matrix/prismlauncher:matrix.org?label=PrismLauncher%20space)](https://matrix.to/#/#prismlauncher:matrix.org) - -We also have a subreddit you can post your issues and suggestions on: - -[r/PrismLauncher](https://www.reddit.com/r/PrismLauncher/) +#### Join our SubReddit: +[![r/PrismLauncher](https://img.shields.io/reddit/subreddit-subscribers/prismlauncher?style=for-the-badge)](https://www.reddit.com/r/PrismLauncher/) ## Building @@ -60,13 +65,11 @@ Be aware that if you build this software without removing the provided API keys If you do not agree with these terms and conditions, then remove the associated API keys from the [CMakeLists.txt](CMakeLists.txt) file by setting them to an empty string (`""`). -## License +## Sponsors & Partners -All launcher code is available under the GPL-3.0-only license. - -The logo and related assets are under the CC BY-SA 4.0 license. +We thank all the wonderful backers over at Open Collective! Support Prism Launcher by [becoming a backer](https://opencollective.com/prismlauncher). -## Sponsors +[![OpenCollective Backers](https://opencollective.com/prismlauncher/backers.svg?width=890&limit=1000)](https://opencollective.com/prismlauncher#backers) Thanks to JetBrains for providing us a few licenses for all their products, as part of their [Open Source program](https://www.jetbrains.com/opensource/). @@ -85,3 +88,12 @@ Thanks to Netlify for providing us their excellent web services, as part of thei Thanks to the awesome people over at [MacStadium](https://www.macstadium.com/), for providing M1-Macs for development purposes! Powered by MacStadium + + +## License + +All launcher code is available under the GPL-3.0-only license. + +![https://github.com/PrismLauncher/PrismLauncher/blob/develop/LICENSE](https://img.shields.io/github/license/PrismLauncher/PrismLauncher?style=for-the-badge) + +The logo and related assets are under the CC BY-SA 4.0 license. diff --git a/buildconfig/BuildConfig.cpp.in b/buildconfig/BuildConfig.cpp.in index 50e5e8a4b..1262ce8e4 100644 --- a/buildconfig/BuildConfig.cpp.in +++ b/buildconfig/BuildConfig.cpp.in @@ -42,12 +42,14 @@ Config::Config() { // Name and copyright LAUNCHER_NAME = "@Launcher_Name@"; + LAUNCHER_APP_BINARY_NAME = "@Launcher_APP_BINARY_NAME@"; LAUNCHER_DISPLAYNAME = "@Launcher_DisplayName@"; LAUNCHER_COPYRIGHT = "@Launcher_Copyright@"; LAUNCHER_DOMAIN = "@Launcher_Domain@"; LAUNCHER_CONFIGFILE = "@Launcher_ConfigFile@"; LAUNCHER_GIT = "@Launcher_Git@"; LAUNCHER_DESKTOPFILENAME = "@Launcher_DesktopFileName@"; + LAUNCHER_SVGFILENAME = "@Launcher_SVGFileName@"; USER_AGENT = "@Launcher_UserAgent@"; USER_AGENT_UNCACHED = USER_AGENT + " (Uncached)"; diff --git a/buildconfig/BuildConfig.h b/buildconfig/BuildConfig.h index ef384ed20..4a3090736 100644 --- a/buildconfig/BuildConfig.h +++ b/buildconfig/BuildConfig.h @@ -44,12 +44,14 @@ class Config { public: Config(); QString LAUNCHER_NAME; + QString LAUNCHER_APP_BINARY_NAME; QString LAUNCHER_DISPLAYNAME; QString LAUNCHER_COPYRIGHT; QString LAUNCHER_DOMAIN; QString LAUNCHER_CONFIGFILE; QString LAUNCHER_GIT; QString LAUNCHER_DESKTOPFILENAME; + QString LAUNCHER_SVGFILENAME; /// The major version number. int VERSION_MAJOR; diff --git a/launcher/Application.cpp b/launcher/Application.cpp index ae832b6bf..3fe463e80 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -62,6 +62,7 @@ #ifdef Q_OS_WIN #include "ui/WinDarkmode.h" +#include #endif #include "ui/setupwizard/SetupWizard.h" @@ -245,7 +246,8 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) {{"s", "server"}, "Join the specified server on launch (only valid in combination with --launch)", "address"}, {{"a", "profile"}, "Use the account specified by its profile name (only valid in combination with --launch)", "profile"}, {"alive", "Write a small '" + liveCheckFile + "' file after the launcher starts"}, - {{"I", "import"}, "Import instance from specified zip (local path or URL)", "file"} + {{"I", "import"}, "Import instance from specified zip (local path or URL)", "file"}, + {"show", "Opens the window for the specified instance (by instance ID)", "show"} }); parser.addHelpOption(); parser.addVersionOption(); @@ -257,6 +259,7 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) m_profileToUse = parser.value("profile"); m_liveCheck = parser.isSet("alive"); m_zipToImport = parser.value("import"); + m_instanceIdToShowWindowOf = parser.value("show"); // error if --launch is missing with --server or --profile if((!m_serverToJoin.isEmpty() || !m_profileToUse.isEmpty()) && m_instanceIdToLaunch.isEmpty()) @@ -498,6 +501,7 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) // Theming m_settings->registerSetting("IconTheme", QString("pe_colored")); m_settings->registerSetting("ApplicationTheme", QString("system")); + m_settings->registerSetting("BackgroundCat", QString("kitteh")); // Remembered state m_settings->registerSetting("LastUsedGroupForNewInstance", QString()); @@ -992,6 +996,16 @@ void Application::performMainStartupAction() return; } } + if(!m_instanceIdToShowWindowOf.isEmpty()) + { + auto inst = instances()->getInstanceById(m_instanceIdToShowWindowOf); + if(inst) + { + qDebug() << "<> Showing window of instance " << m_instanceIdToShowWindowOf; + showInstanceWindow(inst); + return; + } + } if(!m_mainWindow) { // normal main window @@ -1130,15 +1144,6 @@ std::vector Application::getValidApplicationThemes() return ret; } -bool Application::isFlatpak() -{ - #ifdef Q_OS_LINUX - return QFile::exists("/.flatpak-info"); - #else - return false; - #endif -} - void Application::setApplicationTheme(const QString& name, bool initial) { auto systemPalette = qApp->palette(); @@ -1148,7 +1153,7 @@ void Application::setApplicationTheme(const QString& name, bool initial) auto & theme = (*themeIter).second; theme->apply(initial); #ifdef Q_OS_WIN - if (m_mainWindow) { + if (m_mainWindow && IsWindows10OrGreater()) { if (QString::compare(theme->id(), "dark") == 0) { WinDarkmode::setDarkWinTitlebar(m_mainWindow->winId(), true); } else { @@ -1171,7 +1176,7 @@ void Application::setIconTheme(const QString& name) QIcon Application::getThemedIcon(const QString& name) { if(name == "logo") { - return QIcon(":/org.prismlauncher.PrismLauncher.svg"); // FIXME: Make this a BuildConfig variable + return QIcon(":/" + BuildConfig.LAUNCHER_SVGFILENAME); } return QIcon::fromTheme(name); } @@ -1389,10 +1394,13 @@ MainWindow* Application::showMainWindow(bool minimized) m_mainWindow->restoreState(QByteArray::fromBase64(APPLICATION->settings()->get("MainWindowState").toByteArray())); m_mainWindow->restoreGeometry(QByteArray::fromBase64(APPLICATION->settings()->get("MainWindowGeometry").toByteArray())); #ifdef Q_OS_WIN - if (QString::compare(settings()->get("ApplicationTheme").toString(), "dark") == 0) { - WinDarkmode::setDarkWinTitlebar(m_mainWindow->winId(), true); - } else { - WinDarkmode::setDarkWinTitlebar(m_mainWindow->winId(), false); + if (IsWindows10OrGreater()) + { + if (QString::compare(settings()->get("ApplicationTheme").toString(), "dark") == 0) { + WinDarkmode::setDarkWinTitlebar(m_mainWindow->winId(), true); + } else { + WinDarkmode::setDarkWinTitlebar(m_mainWindow->winId(), false); + } } #endif if(minimized) @@ -1577,7 +1585,7 @@ QString Application::getJarPath(QString jarFile) { QStringList potentialPaths = { #if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD) - FS::PathCombine(m_rootPath, "share/jars"), + FS::PathCombine(m_rootPath, "share/" + BuildConfig.LAUNCHER_APP_BINARY_NAME), #endif FS::PathCombine(m_rootPath, "jars"), FS::PathCombine(applicationDirPath(), "jars") diff --git a/launcher/Application.h b/launcher/Application.h index 34ad8c152..8fa0ab10e 100644 --- a/launcher/Application.h +++ b/launcher/Application.h @@ -116,8 +116,6 @@ public: QIcon getThemedIcon(const QString& name); - bool isFlatpak(); - void setIconTheme(const QString& name); std::vector getValidApplicationThemes(); @@ -301,6 +299,7 @@ public: QString m_profileToUse; bool m_liveCheck = false; QUrl m_zipToImport; + QString m_instanceIdToShowWindowOf; std::unique_ptr logFile; }; diff --git a/launcher/BaseInstaller.h b/launcher/BaseInstaller.h index b2e6a14d6..a1b80e93f 100644 --- a/launcher/BaseInstaller.h +++ b/launcher/BaseInstaller.h @@ -17,13 +17,14 @@ #include +#include "BaseVersion.h" + class MinecraftInstance; class QDir; class QString; class QObject; class Task; class BaseVersion; -typedef std::shared_ptr BaseVersionPtr; class BaseInstaller { @@ -35,7 +36,7 @@ public: virtual bool add(MinecraftInstance *to); virtual bool remove(MinecraftInstance *from); - virtual Task *createInstallTask(MinecraftInstance *instance, BaseVersionPtr version, QObject *parent) = 0; + virtual Task *createInstallTask(MinecraftInstance *instance, BaseVersion::Ptr version, QObject *parent) = 0; protected: virtual QString id() const = 0; diff --git a/launcher/BaseVersion.h b/launcher/BaseVersion.h index b88105fb6..ca0e45027 100644 --- a/launcher/BaseVersion.h +++ b/launcher/BaseVersion.h @@ -25,6 +25,7 @@ class BaseVersion { public: + using Ptr = std::shared_ptr; virtual ~BaseVersion() {} /*! * A string used to identify this version in config files. @@ -54,6 +55,4 @@ public: }; }; -typedef std::shared_ptr BaseVersionPtr; - -Q_DECLARE_METATYPE(BaseVersionPtr) +Q_DECLARE_METATYPE(BaseVersion::Ptr) diff --git a/launcher/BaseVersionList.cpp b/launcher/BaseVersionList.cpp index b4a7d6dda..4ed826123 100644 --- a/launcher/BaseVersionList.cpp +++ b/launcher/BaseVersionList.cpp @@ -40,20 +40,20 @@ BaseVersionList::BaseVersionList(QObject *parent) : QAbstractListModel(parent) { } -BaseVersionPtr BaseVersionList::findVersion(const QString &descriptor) +BaseVersion::Ptr BaseVersionList::findVersion(const QString &descriptor) { for (int i = 0; i < count(); i++) { if (at(i)->descriptor() == descriptor) return at(i); } - return BaseVersionPtr(); + return nullptr; } -BaseVersionPtr BaseVersionList::getRecommended() const +BaseVersion::Ptr BaseVersionList::getRecommended() const { if (count() <= 0) - return BaseVersionPtr(); + return nullptr; else return at(0); } @@ -66,7 +66,7 @@ QVariant BaseVersionList::data(const QModelIndex &index, int role) const if (index.row() > count()) return QVariant(); - BaseVersionPtr version = at(index.row()); + BaseVersion::Ptr version = at(index.row()); switch (role) { diff --git a/launcher/BaseVersionList.h b/launcher/BaseVersionList.h index 80a91e8f5..31f29022a 100644 --- a/launcher/BaseVersionList.h +++ b/launcher/BaseVersionList.h @@ -70,7 +70,7 @@ public: virtual bool isLoaded() = 0; //! Gets the version at the given index. - virtual const BaseVersionPtr at(int i) const = 0; + virtual const BaseVersion::Ptr at(int i) const = 0; //! Returns the number of versions in the list. virtual int count() const = 0; @@ -90,13 +90,13 @@ public: * \return A const pointer to the version with the given descriptor. NULL if * one doesn't exist. */ - virtual BaseVersionPtr findVersion(const QString &descriptor); + virtual BaseVersion::Ptr findVersion(const QString &descriptor); /*! * \brief Gets the recommended version from this list * If the list doesn't support recommended versions, this works exactly as getLatestStable */ - virtual BaseVersionPtr getRecommended() const; + virtual BaseVersion::Ptr getRecommended() const; /*! * Sorts the version list. @@ -117,5 +117,5 @@ slots: * then copies the versions and sets their parents correctly. * \param versions List of versions whose parents should be set. */ - virtual void updateListData(QList versions) = 0; + virtual void updateListData(QList versions) = 0; }; diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index 79ac49c76..0dae47df8 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -602,6 +602,7 @@ SET(LAUNCHER_SOURCES resources/OSX/OSX.qrc resources/iOS/iOS.qrc resources/flat/flat.qrc + resources/flat_white/flat_white.qrc resources/documents/documents.qrc ../${Launcher_Branding_LogoQRC} diff --git a/launcher/DesktopServices.cpp b/launcher/DesktopServices.cpp index c29cbe7d0..302eaf967 100644 --- a/launcher/DesktopServices.cpp +++ b/launcher/DesktopServices.cpp @@ -119,7 +119,7 @@ bool openDirectory(const QString &path, bool ensureExists) return QDesktopServices::openUrl(QUrl::fromLocalFile(dir.absolutePath())); }; #if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) - if(!APPLICATION->isFlatpak()) + if(!isFlatpak()) { return IndirectOpen(f); } @@ -140,7 +140,7 @@ bool openFile(const QString &path) return QDesktopServices::openUrl(QUrl::fromLocalFile(path)); }; #if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) - if(!APPLICATION->isFlatpak()) + if(!isFlatpak()) { return IndirectOpen(f); } @@ -158,7 +158,7 @@ bool openFile(const QString &application, const QString &path, const QString &wo qDebug() << "Opening file" << path << "using" << application; #if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) // FIXME: the pid here is fake. So if something depends on it, it will likely misbehave - if(!APPLICATION->isFlatpak()) + if(!isFlatpak()) { return IndirectOpen([&]() { @@ -178,7 +178,7 @@ bool run(const QString &application, const QStringList &args, const QString &wor { qDebug() << "Running" << application << "with args" << args.join(' '); #if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) - if(!APPLICATION->isFlatpak()) + if(!isFlatpak()) { // FIXME: the pid here is fake. So if something depends on it, it will likely misbehave return IndirectOpen([&]() @@ -203,7 +203,7 @@ bool openUrl(const QUrl &url) return QDesktopServices::openUrl(url); }; #if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) - if(!APPLICATION->isFlatpak()) + if(!isFlatpak()) { return IndirectOpen(f); } @@ -216,4 +216,13 @@ bool openUrl(const QUrl &url) #endif } +bool isFlatpak() +{ +#ifdef Q_OS_LINUX + return QFile::exists("/.flatpak-info"); +#else + return false; +#endif +} + } diff --git a/launcher/DesktopServices.h b/launcher/DesktopServices.h index 1c081da41..21c9cae0b 100644 --- a/launcher/DesktopServices.h +++ b/launcher/DesktopServices.h @@ -33,4 +33,6 @@ namespace DesktopServices * Open the URL, most likely in a browser. Maybe. */ bool openUrl(const QUrl &url); + + bool isFlatpak(); } diff --git a/launcher/FileSystem.cpp b/launcher/FileSystem.cpp index 39e68c207..4026d6c16 100644 --- a/launcher/FileSystem.cpp +++ b/launcher/FileSystem.cpp @@ -44,6 +44,7 @@ #include #include #include +#include "DesktopServices.h" #if defined Q_OS_WIN32 #include @@ -182,6 +183,21 @@ bool copy::operator()(const QString& offset) if (!m_followSymlinks) opt |= copy_opts::copy_symlinks; + // Function that'll do the actual copying + auto copy_file = [&](QString src_path, QString relative_dst_path) { + if (m_blacklist && m_blacklist->matches(relative_dst_path)) + return; + + auto dst_path = PathCombine(dst, relative_dst_path); + ensureFilePathExists(dst_path); + + fs::copy(toStdString(src_path), toStdString(dst_path), opt, err); + if (err) { + qWarning() << "Failed to copy files:" << QString::fromStdString(err.message()); + qDebug() << "Source file:" << src_path; + qDebug() << "Destination file:" << dst_path; + } + }; // We can't use copy_opts::recursive because we need to take into account the // blacklisted paths, so we iterate over the source directory, and if there's no blacklist @@ -193,20 +209,13 @@ bool copy::operator()(const QString& offset) auto src_path = source_it.next(); auto relative_path = src_dir.relativeFilePath(src_path); - if (m_blacklist && m_blacklist->matches(relative_path)) - continue; - - auto dst_path = PathCombine(dst, relative_path); - ensureFilePathExists(dst_path); - - fs::copy(toStdString(src_path), toStdString(dst_path), opt, err); - if (err) { - qWarning() << "Failed to copy files:" << QString::fromStdString(err.message()); - qDebug() << "Source file:" << src_path; - qDebug() << "Destination file:" << dst_path; - } + copy_file(src_path, relative_path); } + // If the root src is not a directory, the previous iterator won't run. + if (!fs::is_directory(toStdString(src))) + copy_file(src, ""); + return err.value() == 0; } @@ -228,6 +237,9 @@ bool trash(QString path, QString *pathInTrash = nullptr) #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0) return false; #else + // FIXME: Figure out trash in Flatpak. Qt seemingly doesn't use the Trash portal + if (DesktopServices::isFlatpak()) + return false; return QFile::moveToTrash(path, pathInTrash); #endif } @@ -401,6 +413,7 @@ bool overrideFolder(QString overwritten_path, QString override_path) std::error_code err; fs::copy_options opt = copy_opts::recursive | copy_opts::overwrite_existing; + // FIXME: hello traveller! Apparently std::copy does NOT overwrite existing files on GNU libstdc++ on Windows? fs::copy(toStdString(override_path), toStdString(overwritten_path), opt, err); if (err) { diff --git a/launcher/GZip.cpp b/launcher/GZip.cpp index 067104cff..e36dc8a49 100644 --- a/launcher/GZip.cpp +++ b/launcher/GZip.cpp @@ -72,7 +72,7 @@ bool GZip::unzip(const QByteArray &compressedBytes, QByteArray &uncompressedByte uncompLength *= 2; } - strm.next_out = (Bytef *)(uncompressedBytes.data() + strm.total_out); + strm.next_out = reinterpret_cast((uncompressedBytes.data() + strm.total_out)); strm.avail_out = uncompLength - strm.total_out; // Inflate another chunk. @@ -129,7 +129,7 @@ bool GZip::zip(const QByteArray &uncompressedBytes, QByteArray &compressedBytes) { compressedBytes.resize(compressedBytes.size() * 2); } - zs.next_out = (Bytef *) (compressedBytes.data() + offset); + zs.next_out = reinterpret_cast((compressedBytes.data() + offset)); temp = zs.avail_out = compressedBytes.size() - offset; ret = deflate(&zs, Z_FINISH); offset += temp - zs.avail_out; diff --git a/launcher/HoeDown.h b/launcher/HoeDown.h index b9e06ffbc..cb62de6cf 100644 --- a/launcher/HoeDown.h +++ b/launcher/HoeDown.h @@ -42,7 +42,7 @@ public: } void put(QByteArray input) { - hoedown_buffer_put(buf, (uint8_t *) input.data(), input.size()); + hoedown_buffer_put(buf, reinterpret_cast(input.data()), input.size()); } const uint8_t * data() const { diff --git a/launcher/java/JavaInstallList.cpp b/launcher/java/JavaInstallList.cpp index 0249bd22e..155c956a2 100644 --- a/launcher/java/JavaInstallList.cpp +++ b/launcher/java/JavaInstallList.cpp @@ -73,7 +73,7 @@ void JavaInstallList::load() } } -const BaseVersionPtr JavaInstallList::at(int i) const +const BaseVersion::Ptr JavaInstallList::at(int i) const { return m_vlist.at(i); } @@ -122,7 +122,7 @@ BaseVersionList::RoleList JavaInstallList::providesRoles() const } -void JavaInstallList::updateListData(QList versions) +void JavaInstallList::updateListData(QList versions) { beginResetModel(); m_vlist = versions; @@ -137,7 +137,7 @@ void JavaInstallList::updateListData(QList versions) m_loadTask.reset(); } -bool sortJavas(BaseVersionPtr left, BaseVersionPtr right) +bool sortJavas(BaseVersion::Ptr left, BaseVersion::Ptr right) { auto rleft = std::dynamic_pointer_cast(right); auto rright = std::dynamic_pointer_cast(left); @@ -210,11 +210,11 @@ void JavaListLoadTask::javaCheckerFinished() } } - QList javas_bvp; + QList javas_bvp; for (auto java : candidates) { //qDebug() << java->id << java->arch << " at " << java->path; - BaseVersionPtr bp_java = std::dynamic_pointer_cast(java); + BaseVersion::Ptr bp_java = std::dynamic_pointer_cast(java); if (bp_java) { diff --git a/launcher/java/JavaInstallList.h b/launcher/java/JavaInstallList.h index 3c237edf1..733dc7e1c 100644 --- a/launcher/java/JavaInstallList.h +++ b/launcher/java/JavaInstallList.h @@ -42,7 +42,7 @@ public: Task::Ptr getLoadTask() override; bool isLoaded() override; - const BaseVersionPtr at(int i) const override; + const BaseVersion::Ptr at(int i) const override; int count() const override; void sortVersions() override; @@ -50,7 +50,7 @@ public: RoleList providesRoles() const override; public slots: - void updateListData(QList versions) override; + void updateListData(QList versions) override; protected: void load(); @@ -59,7 +59,7 @@ protected: protected: Status m_status = Status::NotDone; shared_qobject_ptr m_loadTask; - QList m_vlist; + QList m_vlist; }; class JavaListLoadTask : public Task diff --git a/launcher/java/JavaUtils.cpp b/launcher/java/JavaUtils.cpp index 040fe8210..6c0c60cd3 100644 --- a/launcher/java/JavaUtils.cpp +++ b/launcher/java/JavaUtils.cpp @@ -379,7 +379,9 @@ QList JavaUtils::FindJavaPaths() } } - return addJavasFromEnv(candidates); + candidates = addJavasFromEnv(candidates); + candidates.removeDuplicates(); + return candidates; } #elif defined(Q_OS_MAC) @@ -402,7 +404,9 @@ QList JavaUtils::FindJavaPaths() javas.append(systemLibraryJVMDir.absolutePath() + "/" + java + "/Contents/Home/bin/java"); javas.append(systemLibraryJVMDir.absolutePath() + "/" + java + "/Contents/Commands/java"); } - return addJavasFromEnv(javas); + javas = addJavasFromEnv(javas); + javas.removeDuplicates(); + return javas; } #elif defined(Q_OS_LINUX) @@ -448,7 +452,9 @@ QList JavaUtils::FindJavaPaths() scanJavaDir("/opt/jdks"); // flatpak scanJavaDir("/app/jdk"); - return addJavasFromEnv(javas); + javas = addJavasFromEnv(javas); + javas.removeDuplicates(); + return javas; } #else QList JavaUtils::FindJavaPaths() diff --git a/launcher/main.cpp b/launcher/main.cpp index c6a7614c4..e2116f384 100644 --- a/launcher/main.cpp +++ b/launcher/main.cpp @@ -84,6 +84,7 @@ int main(int argc, char *argv[]) Q_INIT_RESOURCE(OSX); Q_INIT_RESOURCE(iOS); Q_INIT_RESOURCE(flat); + Q_INIT_RESOURCE(flat_white); return app.exec(); } case Application::Failed: diff --git a/launcher/meta/Index.cpp b/launcher/meta/Index.cpp index 6802470d9..eec1b329b 100644 --- a/launcher/meta/Index.cpp +++ b/launcher/meta/Index.cpp @@ -24,7 +24,7 @@ Index::Index(QObject *parent) : QAbstractListModel(parent) { } -Index::Index(const QVector &lists, QObject *parent) +Index::Index(const QVector &lists, QObject *parent) : QAbstractListModel(parent), m_lists(lists) { for (int i = 0; i < m_lists.size(); ++i) @@ -41,7 +41,7 @@ QVariant Index::data(const QModelIndex &index, int role) const return QVariant(); } - VersionListPtr list = m_lists.at(index.row()); + VersionList::Ptr list = m_lists.at(index.row()); switch (role) { case Qt::DisplayRole: @@ -81,9 +81,9 @@ bool Index::hasUid(const QString &uid) const return m_uids.contains(uid); } -VersionListPtr Index::get(const QString &uid) +VersionList::Ptr Index::get(const QString &uid) { - VersionListPtr out = m_uids.value(uid, nullptr); + VersionList::Ptr out = m_uids.value(uid, nullptr); if(!out) { out = std::make_shared(uid); @@ -92,7 +92,7 @@ VersionListPtr Index::get(const QString &uid) return out; } -VersionPtr Index::get(const QString &uid, const QString &version) +Version::Ptr Index::get(const QString &uid, const QString &version) { auto list = get(uid); return list->getVersion(version); @@ -105,7 +105,7 @@ void Index::parse(const QJsonObject& obj) void Index::merge(const std::shared_ptr &other) { - const QVector lists = std::dynamic_pointer_cast(other)->m_lists; + const QVector lists = std::dynamic_pointer_cast(other)->m_lists; // initial load, no need to merge if (m_lists.isEmpty()) { @@ -120,7 +120,7 @@ void Index::merge(const std::shared_ptr &other) } else { - for (const VersionListPtr &list : lists) + for (const VersionList::Ptr &list : lists) { if (m_uids.contains(list->uid())) { @@ -138,7 +138,7 @@ void Index::merge(const std::shared_ptr &other) } } -void Index::connectVersionList(const int row, const VersionListPtr &list) +void Index::connectVersionList(const int row, const VersionList::Ptr &list) { connect(list.get(), &VersionList::nameChanged, this, [this, row]() { diff --git a/launcher/meta/Index.h b/launcher/meta/Index.h index d33ab0c89..06ea09dcf 100644 --- a/launcher/meta/Index.h +++ b/launcher/meta/Index.h @@ -19,20 +19,19 @@ #include #include "BaseEntity.h" +#include "meta/VersionList.h" class Task; namespace Meta { -using VersionListPtr = std::shared_ptr; -using VersionPtr = std::shared_ptr; class Index : public QAbstractListModel, public BaseEntity { Q_OBJECT public: explicit Index(QObject *parent = nullptr); - explicit Index(const QVector &lists, QObject *parent = nullptr); + explicit Index(const QVector &lists, QObject *parent = nullptr); enum { @@ -49,21 +48,21 @@ public: QString localFilename() const override { return "index.json"; } // queries - VersionListPtr get(const QString &uid); - VersionPtr get(const QString &uid, const QString &version); + VersionList::Ptr get(const QString &uid); + Version::Ptr get(const QString &uid, const QString &version); bool hasUid(const QString &uid) const; - QVector lists() const { return m_lists; } + QVector lists() const { return m_lists; } public: // for usage by parsers only void merge(const std::shared_ptr &other); void parse(const QJsonObject &obj) override; private: - QVector m_lists; - QHash m_uids; + QVector m_lists; + QHash m_uids; - void connectVersionList(const int row, const VersionListPtr &list); + void connectVersionList(const int row, const VersionList::Ptr &list); }; } diff --git a/launcher/meta/JsonFormat.cpp b/launcher/meta/JsonFormat.cpp index 796da4bb6..473f37d66 100644 --- a/launcher/meta/JsonFormat.cpp +++ b/launcher/meta/JsonFormat.cpp @@ -37,11 +37,11 @@ MetadataVersion currentFormatVersion() static std::shared_ptr parseIndexInternal(const QJsonObject &obj) { const QVector objects = requireIsArrayOf(obj, "packages"); - QVector lists; + QVector lists; lists.reserve(objects.size()); std::transform(objects.begin(), objects.end(), std::back_inserter(lists), [](const QJsonObject &obj) { - VersionListPtr list = std::make_shared(requireString(obj, "uid")); + VersionList::Ptr list = std::make_shared(requireString(obj, "uid")); list->setName(ensureString(obj, "name", QString())); return list; }); @@ -49,9 +49,9 @@ static std::shared_ptr parseIndexInternal(const QJsonObject &obj) } // Version -static VersionPtr parseCommonVersion(const QString &uid, const QJsonObject &obj) +static Version::Ptr parseCommonVersion(const QString &uid, const QJsonObject &obj) { - VersionPtr version = std::make_shared(uid, requireString(obj, "version")); + Version::Ptr version = std::make_shared(uid, requireString(obj, "version")); version->setTime(QDateTime::fromString(requireString(obj, "releaseTime"), Qt::ISODate).toMSecsSinceEpoch() / 1000); version->setType(ensureString(obj, "type", QString())); version->setRecommended(ensureBoolean(obj, QString("recommended"), false)); @@ -63,9 +63,9 @@ static VersionPtr parseCommonVersion(const QString &uid, const QJsonObject &obj) return version; } -static std::shared_ptr parseVersionInternal(const QJsonObject &obj) +static Version::Ptr parseVersionInternal(const QJsonObject &obj) { - VersionPtr version = parseCommonVersion(requireString(obj, "uid"), obj); + Version::Ptr version = parseCommonVersion(requireString(obj, "uid"), obj); version->setData(OneSixVersionFormat::versionFileFromJson(QJsonDocument(obj), QString("%1/%2.json").arg(version->uid(), version->version()), @@ -74,12 +74,12 @@ static std::shared_ptr parseVersionInternal(const QJsonObject &obj) } // Version list / package -static std::shared_ptr parseVersionListInternal(const QJsonObject &obj) +static VersionList::Ptr parseVersionListInternal(const QJsonObject &obj) { const QString uid = requireString(obj, "uid"); const QVector versionsRaw = requireIsArrayOf(obj, "versions"); - QVector versions; + QVector versions; versions.reserve(versionsRaw.size()); std::transform(versionsRaw.begin(), versionsRaw.end(), std::back_inserter(versions), [uid](const QJsonObject &vObj) { @@ -88,7 +88,7 @@ static std::shared_ptr parseVersionListInternal(const QJsonObject & return version; }); - VersionListPtr list = std::make_shared(uid); + VersionList::Ptr list = std::make_shared(uid); list->setName(ensureString(obj, "name", QString())); list->setVersions(versions); return list; diff --git a/launcher/meta/Version.cpp b/launcher/meta/Version.cpp index a8dc3169d..68cfa55c8 100644 --- a/launcher/meta/Version.cpp +++ b/launcher/meta/Version.cpp @@ -54,7 +54,7 @@ void Meta::Version::parse(const QJsonObject& obj) parseVersion(obj, this); } -void Meta::Version::mergeFromList(const Meta::VersionPtr& other) +void Meta::Version::mergeFromList(const Meta::Version::Ptr& other) { if(other->m_providesRecommendations) { @@ -85,7 +85,7 @@ void Meta::Version::mergeFromList(const Meta::VersionPtr& other) } } -void Meta::Version::merge(const VersionPtr &other) +void Meta::Version::merge(const Version::Ptr &other) { mergeFromList(other); if(other->m_data) diff --git a/launcher/meta/Version.h b/launcher/meta/Version.h index dea8dc8a3..7228fa366 100644 --- a/launcher/meta/Version.h +++ b/launcher/meta/Version.h @@ -30,13 +30,14 @@ namespace Meta { -using VersionPtr = std::shared_ptr; class Version : public QObject, public BaseVersion, public BaseEntity { Q_OBJECT -public: /* con/des */ +public: + using Ptr = std::shared_ptr; + explicit Version(const QString &uid, const QString &version); virtual ~Version(); @@ -78,8 +79,8 @@ public: /* con/des */ return m_data != nullptr; } - void merge(const VersionPtr &other); - void mergeFromList(const VersionPtr &other); + void merge(const Version::Ptr &other); + void mergeFromList(const Version::Ptr &other); void parse(const QJsonObject &obj) override; QString localFilename() const override; @@ -113,4 +114,4 @@ private: }; } -Q_DECLARE_METATYPE(Meta::VersionPtr) +Q_DECLARE_METATYPE(Meta::Version::Ptr) diff --git a/launcher/meta/VersionList.cpp b/launcher/meta/VersionList.cpp index f609e94c3..7f001dfc2 100644 --- a/launcher/meta/VersionList.cpp +++ b/launcher/meta/VersionList.cpp @@ -40,7 +40,7 @@ bool VersionList::isLoaded() return BaseEntity::isLoaded(); } -const BaseVersionPtr VersionList::at(int i) const +const BaseVersion::Ptr VersionList::at(int i) const { return m_versions.at(i); } @@ -52,7 +52,7 @@ int VersionList::count() const void VersionList::sortVersions() { beginResetModel(); - std::sort(m_versions.begin(), m_versions.end(), [](const VersionPtr &a, const VersionPtr &b) + std::sort(m_versions.begin(), m_versions.end(), [](const Version::Ptr &a, const Version::Ptr &b) { return *a.get() < *b.get(); }); @@ -66,7 +66,7 @@ QVariant VersionList::data(const QModelIndex &index, int role) const return QVariant(); } - VersionPtr version = m_versions.at(index.row()); + Version::Ptr version = m_versions.at(index.row()); switch (role) { @@ -129,9 +129,9 @@ QString VersionList::humanReadable() const return m_name.isEmpty() ? m_uid : m_name; } -VersionPtr VersionList::getVersion(const QString &version) +Version::Ptr VersionList::getVersion(const QString &version) { - VersionPtr out = m_lookup.value(version, nullptr); + Version::Ptr out = m_lookup.value(version, nullptr); if(!out) { out = std::make_shared(m_uid, version); @@ -143,7 +143,7 @@ VersionPtr VersionList::getVersion(const QString &version) bool VersionList::hasVersion(QString version) const { auto ver = std::find_if(m_versions.constBegin(), m_versions.constEnd(), - [&](Meta::VersionPtr const& a){ return a->version() == version; }); + [&](Meta::Version::Ptr const& a){ return a->version() == version; }); return (ver != m_versions.constEnd()); } @@ -153,11 +153,11 @@ void VersionList::setName(const QString &name) emit nameChanged(name); } -void VersionList::setVersions(const QVector &versions) +void VersionList::setVersions(const QVector &versions) { beginResetModel(); m_versions = versions; - std::sort(m_versions.begin(), m_versions.end(), [](const VersionPtr &a, const VersionPtr &b) + std::sort(m_versions.begin(), m_versions.end(), [](const Version::Ptr &a, const Version::Ptr &b) { return a->rawTime() > b->rawTime(); }); @@ -168,7 +168,7 @@ void VersionList::setVersions(const QVector &versions) } // FIXME: this is dumb, we have 'recommended' as part of the metadata already... - auto recommendedIt = std::find_if(m_versions.constBegin(), m_versions.constEnd(), [](const VersionPtr &ptr) { return ptr->type() == "release"; }); + auto recommendedIt = std::find_if(m_versions.constBegin(), m_versions.constEnd(), [](const Version::Ptr &ptr) { return ptr->type() == "release"; }); m_recommended = recommendedIt == m_versions.constEnd() ? nullptr : *recommendedIt; endResetModel(); } @@ -179,7 +179,7 @@ void VersionList::parse(const QJsonObject& obj) } // FIXME: this is dumb, we have 'recommended' as part of the metadata already... -static const Meta::VersionPtr &getBetterVersion(const Meta::VersionPtr &a, const Meta::VersionPtr &b) +static const Meta::Version::Ptr &getBetterVersion(const Meta::Version::Ptr &a, const Meta::Version::Ptr &b) { if(!a) return b; @@ -194,7 +194,7 @@ static const Meta::VersionPtr &getBetterVersion(const Meta::VersionPtr &a, const return (a->type() == "release" ? a : b); } -void VersionList::mergeFromIndex(const VersionListPtr &other) +void VersionList::mergeFromIndex(const VersionList::Ptr &other) { if (m_name != other->m_name) { @@ -202,7 +202,7 @@ void VersionList::mergeFromIndex(const VersionListPtr &other) } } -void VersionList::merge(const VersionListPtr &other) +void VersionList::merge(const VersionList::Ptr &other) { if (m_name != other->m_name) { @@ -216,7 +216,7 @@ void VersionList::merge(const VersionListPtr &other) { qWarning() << "Empty list loaded ..."; } - for (const VersionPtr &version : other->m_versions) + for (const Version::Ptr &version : other->m_versions) { // we already have the version. merge the contents if (m_lookup.contains(version->version())) @@ -235,7 +235,7 @@ void VersionList::merge(const VersionListPtr &other) endResetModel(); } -void VersionList::setupAddedVersion(const int row, const VersionPtr &version) +void VersionList::setupAddedVersion(const int row, const Version::Ptr &version) { // FIXME: do not disconnect from everythin, disconnect only the lambdas here version->disconnect(); @@ -244,7 +244,7 @@ void VersionList::setupAddedVersion(const int row, const VersionPtr &version) connect(version.get(), &Version::typeChanged, this, [this, row]() { emit dataChanged(index(row), index(row), QVector() << TypeRole); }); } -BaseVersionPtr VersionList::getRecommended() const +BaseVersion::Ptr VersionList::getRecommended() const { return m_recommended; } diff --git a/launcher/meta/VersionList.h b/launcher/meta/VersionList.h index a6db2fd73..a4d5603d9 100644 --- a/launcher/meta/VersionList.h +++ b/launcher/meta/VersionList.h @@ -20,10 +20,10 @@ #include #include +#include "meta/Version.h" + namespace Meta { -using VersionPtr = std::shared_ptr; -using VersionListPtr = std::shared_ptr; class VersionList : public BaseVersionList, public BaseEntity { @@ -33,6 +33,8 @@ class VersionList : public BaseVersionList, public BaseEntity public: explicit VersionList(const QString &uid, QObject *parent = nullptr); + using Ptr = std::shared_ptr; + enum Roles { UidRole = Qt::UserRole + 100, @@ -43,11 +45,11 @@ public: Task::Ptr getLoadTask() override; bool isLoaded() override; - const BaseVersionPtr at(int i) const override; + const BaseVersion::Ptr at(int i) const override; int count() const override; void sortVersions() override; - BaseVersionPtr getRecommended() const override; + BaseVersion::Ptr getRecommended() const override; QVariant data(const QModelIndex &index, int role) const override; RoleList providesRoles() const override; @@ -65,38 +67,38 @@ public: } QString humanReadable() const; - VersionPtr getVersion(const QString &version); + Version::Ptr getVersion(const QString &version); bool hasVersion(QString version) const; - QVector versions() const + QVector versions() const { return m_versions; } public: // for usage only by parsers void setName(const QString &name); - void setVersions(const QVector &versions); - void merge(const VersionListPtr &other); - void mergeFromIndex(const VersionListPtr &other); + void setVersions(const QVector &versions); + void merge(const VersionList::Ptr &other); + void mergeFromIndex(const VersionList::Ptr &other); void parse(const QJsonObject &obj) override; signals: void nameChanged(const QString &name); protected slots: - void updateListData(QList) override + void updateListData(QList) override { } private: - QVector m_versions; - QHash m_lookup; + QVector m_versions; + QHash m_lookup; QString m_uid; QString m_name; - VersionPtr m_recommended; + Version::Ptr m_recommended; - void setupAddedVersion(const int row, const VersionPtr &version); + void setupAddedVersion(const int row, const Version::Ptr &version); }; } -Q_DECLARE_METATYPE(Meta::VersionListPtr) +Q_DECLARE_METATYPE(Meta::VersionList::Ptr) diff --git a/launcher/minecraft/VanillaInstanceCreationTask.cpp b/launcher/minecraft/VanillaInstanceCreationTask.cpp index c45daa9a8..0bb92e876 100644 --- a/launcher/minecraft/VanillaInstanceCreationTask.cpp +++ b/launcher/minecraft/VanillaInstanceCreationTask.cpp @@ -7,7 +7,7 @@ #include "minecraft/PackProfile.h" #include "settings/INISettingsObject.h" -VanillaCreationTask::VanillaCreationTask(BaseVersionPtr version, QString loader, BaseVersionPtr loader_version) +VanillaCreationTask::VanillaCreationTask(BaseVersion::Ptr version, QString loader, BaseVersion::Ptr loader_version) : InstanceCreationTask(), m_version(std::move(version)), m_using_loader(true), m_loader(std::move(loader)), m_loader_version(std::move(loader_version)) {} diff --git a/launcher/minecraft/VanillaInstanceCreationTask.h b/launcher/minecraft/VanillaInstanceCreationTask.h index 7a37bbd6a..d1b816824 100644 --- a/launcher/minecraft/VanillaInstanceCreationTask.h +++ b/launcher/minecraft/VanillaInstanceCreationTask.h @@ -7,16 +7,16 @@ class VanillaCreationTask final : public InstanceCreationTask { Q_OBJECT public: - VanillaCreationTask(BaseVersionPtr version) : InstanceCreationTask(), m_version(std::move(version)) {} - VanillaCreationTask(BaseVersionPtr version, QString loader, BaseVersionPtr loader_version); + VanillaCreationTask(BaseVersion::Ptr version) : InstanceCreationTask(), m_version(std::move(version)) {} + VanillaCreationTask(BaseVersion::Ptr version, QString loader, BaseVersion::Ptr loader_version); bool createInstance() override; private: // Version to update to / create of the instance. - BaseVersionPtr m_version; + BaseVersion::Ptr m_version; bool m_using_loader = false; QString m_loader; - BaseVersionPtr m_loader_version; + BaseVersion::Ptr m_loader_version; }; diff --git a/launcher/minecraft/launch/VerifyJavaInstall.cpp b/launcher/minecraft/launch/VerifyJavaInstall.cpp index 99809f828..6ae666b47 100644 --- a/launcher/minecraft/launch/VerifyJavaInstall.cpp +++ b/launcher/minecraft/launch/VerifyJavaInstall.cpp @@ -71,5 +71,7 @@ void VerifyJavaInstall::executeTask() { { emit logLine(tr("Java version %1").arg(major), MessageLevel::Error); } + emit logLine(tr("Go to instance Java settings to change your Java version or disable the Java compatibility check if you know what you're doing."), MessageLevel::Error); + emitFailed(QString("Incompatible Java major version")); } diff --git a/launcher/modplatform/atlauncher/ATLPackInstallTask.cpp b/launcher/modplatform/atlauncher/ATLPackInstallTask.cpp index a553eafd1..291ad9161 100644 --- a/launcher/modplatform/atlauncher/ATLPackInstallTask.cpp +++ b/launcher/modplatform/atlauncher/ATLPackInstallTask.cpp @@ -58,7 +58,7 @@ namespace ATLauncher { -static Meta::VersionPtr getComponentVersion(const QString& uid, const QString& version); +static Meta::Version::Ptr getComponentVersion(const QString& uid, const QString& version); PackInstallTask::PackInstallTask(UserInteractionSupport *support, QString packName, QString version, InstallMode installMode) { @@ -736,7 +736,12 @@ void PackInstallTask::downloadMods() QVector selectedMods; if (!optionalMods.isEmpty()) { setStatus(tr("Selecting optional mods...")); - selectedMods = m_support->chooseOptionalMods(m_version, optionalMods); + auto mods = m_support->chooseOptionalMods(m_version, optionalMods); + if (!mods.has_value()) { + emitAborted(); + return; + } + selectedMods = mods.value(); } setStatus(tr("Downloading mods...")); @@ -1032,7 +1037,7 @@ void PackInstallTask::install() emitSucceeded(); } -static Meta::VersionPtr getComponentVersion(const QString& uid, const QString& version) +static Meta::Version::Ptr getComponentVersion(const QString& uid, const QString& version) { auto vlist = APPLICATION->metadataIndex()->get(uid); if (!vlist) diff --git a/launcher/modplatform/atlauncher/ATLPackInstallTask.h b/launcher/modplatform/atlauncher/ATLPackInstallTask.h index ed4436f07..90e25ae2e 100644 --- a/launcher/modplatform/atlauncher/ATLPackInstallTask.h +++ b/launcher/modplatform/atlauncher/ATLPackInstallTask.h @@ -62,13 +62,13 @@ public: /** * Requests a user interaction to select which optional mods should be installed. */ - virtual QVector chooseOptionalMods(PackVersion version, QVector mods) = 0; + virtual std::optional> chooseOptionalMods(PackVersion version, QVector mods) = 0; /** * Requests a user interaction to select a component version from a given version list * and constrained to a given Minecraft version. */ - virtual QString chooseVersion(Meta::VersionListPtr vlist, QString minecraftVersion) = 0; + virtual QString chooseVersion(Meta::VersionList::Ptr vlist, QString minecraftVersion) = 0; /** * Requests a user interaction to display a message. @@ -137,8 +137,8 @@ private: QString archivePath; QStringList jarmods; - Meta::VersionPtr minecraftVersion; - QMap componentsToInstall; + Meta::Version::Ptr minecraftVersion; + QMap componentsToInstall; QFuture> m_extractFuture; QFutureWatcher> m_extractFutureWatcher; diff --git a/launcher/modplatform/flame/FileResolvingTask.cpp b/launcher/modplatform/flame/FileResolvingTask.cpp index 1e7f55590..25b56fbd1 100644 --- a/launcher/modplatform/flame/FileResolvingTask.cpp +++ b/launcher/modplatform/flame/FileResolvingTask.cpp @@ -3,6 +3,8 @@ #include "Json.h" #include "net/Upload.h" +#include "modplatform/modrinth/ModrinthPackIndex.h" + Flame::FileResolvingTask::FileResolvingTask(const shared_qobject_ptr& network, Flame::Manifest& toProcess) : m_network(network), m_toProcess(toProcess) {} @@ -12,6 +14,8 @@ bool Flame::FileResolvingTask::abort() bool aborted = true; if (m_dljob) aborted &= m_dljob->abort(); + if (m_checkJob) + aborted &= m_checkJob->abort(); return aborted ? Task::abort() : false; } @@ -40,7 +44,7 @@ void Flame::FileResolvingTask::netJobFinished() setProgress(1, 3); int index = 0; // job to check modrinth for blocked projects - auto job = new NetJob("Modrinth check", m_network); + m_checkJob = new NetJob("Modrinth check", m_network); blockedProjects = QMap(); auto doc = Json::requireDocument(*result); auto array = Json::requireArray(doc.object()["data"]); @@ -60,15 +64,15 @@ void Flame::FileResolvingTask::netJobFinished() out.resolved = true; }); - job->addNetAction(dl); + m_checkJob->addNetAction(dl); blockedProjects.insert(&out, output); } } index++; } - connect(job, &NetJob::finished, this, &Flame::FileResolvingTask::modrinthCheckFinished); + connect(m_checkJob.get(), &NetJob::finished, this, &Flame::FileResolvingTask::modrinthCheckFinished); - job->start(); + m_checkJob->start(); } void Flame::FileResolvingTask::modrinthCheckFinished() { @@ -82,18 +86,21 @@ void Flame::FileResolvingTask::modrinthCheckFinished() { delete bytes; continue; } + QJsonDocument doc = QJsonDocument::fromJson(*bytes); auto obj = doc.object(); - auto array = Json::requireArray(obj,"files"); - for (auto file: array) { - auto fileObj = Json::requireObject(file); - auto primary = Json::requireBoolean(fileObj,"primary"); - if (primary) { - out->url = Json::requireUrl(fileObj,"url"); - qDebug() << "Found alternative on modrinth " << out->fileName; - break; - } + auto file = Modrinth::loadIndexedPackVersion(obj); + + // If there's more than one mod loader for this version, we can't know for sure + // which file is relative to each loader, so it's best to not use any one and + // let the user download it manually. + if (file.loaders.size() <= 1) { + out->url = file.downloadUrl; + qDebug() << "Found alternative on modrinth " << out->fileName; + } else { + out->resolved = false; } + delete bytes; } //copy to an output list and filter out projects found on modrinth diff --git a/launcher/modplatform/flame/FileResolvingTask.h b/launcher/modplatform/flame/FileResolvingTask.h index f71b87ceb..8fc17ea91 100644 --- a/launcher/modplatform/flame/FileResolvingTask.h +++ b/launcher/modplatform/flame/FileResolvingTask.h @@ -30,8 +30,9 @@ protected slots: private: /* data */ shared_qobject_ptr m_network; Flame::Manifest m_toProcess; - std::shared_ptr result; + std::shared_ptr result; NetJob::Ptr m_dljob; + NetJob::Ptr m_checkJob; void modrinthCheckFinished(); diff --git a/launcher/modplatform/helpers/NetworkModAPI.cpp b/launcher/modplatform/helpers/NetworkModAPI.cpp index 866e7540c..7633030e1 100644 --- a/launcher/modplatform/helpers/NetworkModAPI.cpp +++ b/launcher/modplatform/helpers/NetworkModAPI.cpp @@ -15,6 +15,7 @@ void NetworkModAPI::searchMods(CallerType* caller, SearchArgs&& args) const QObject::connect(netJob, &NetJob::started, caller, [caller, netJob] { caller->setActiveJob(netJob); }); QObject::connect(netJob, &NetJob::failed, caller, &CallerType::searchRequestFailed); + QObject::connect(netJob, &NetJob::aborted, caller, &CallerType::searchRequestAborted); QObject::connect(netJob, &NetJob::succeeded, caller, [caller, response] { QJsonParseError parse_error{}; QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error); diff --git a/launcher/modplatform/modrinth/ModrinthPackIndex.cpp b/launcher/modplatform/modrinth/ModrinthPackIndex.cpp index 3e53becb4..ae45e0966 100644 --- a/launcher/modplatform/modrinth/ModrinthPackIndex.cpp +++ b/launcher/modplatform/modrinth/ModrinthPackIndex.cpp @@ -1,20 +1,20 @@ // SPDX-License-Identifier: GPL-3.0-only /* -* PolyMC - Minecraft Launcher -* Copyright (c) 2022 flowln -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, version 3. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*/ + * PolyMC - Minecraft Launcher + * Copyright (c) 2022 flowln + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ #include "ModrinthPackIndex.h" #include "ModrinthAPI.h" @@ -35,7 +35,7 @@ void Modrinth::loadIndexedPack(ModPlatform::IndexedPack& pack, QJsonObject& obj) pack.provider = ModPlatform::Provider::MODRINTH; pack.name = Json::requireString(obj, "title"); - + pack.slug = Json::ensureString(obj, "slug", ""); if (!pack.slug.isEmpty()) pack.websiteUrl = "https://modrinth.com/mod/" + pack.slug; @@ -59,23 +59,23 @@ void Modrinth::loadIndexedPack(ModPlatform::IndexedPack& pack, QJsonObject& obj) void Modrinth::loadExtraPackData(ModPlatform::IndexedPack& pack, QJsonObject& obj) { pack.extraData.issuesUrl = Json::ensureString(obj, "issues_url"); - if(pack.extraData.issuesUrl.endsWith('/')) + if (pack.extraData.issuesUrl.endsWith('/')) pack.extraData.issuesUrl.chop(1); pack.extraData.sourceUrl = Json::ensureString(obj, "source_url"); - if(pack.extraData.sourceUrl.endsWith('/')) + if (pack.extraData.sourceUrl.endsWith('/')) pack.extraData.sourceUrl.chop(1); pack.extraData.wikiUrl = Json::ensureString(obj, "wiki_url"); - if(pack.extraData.wikiUrl.endsWith('/')) + if (pack.extraData.wikiUrl.endsWith('/')) pack.extraData.wikiUrl.chop(1); pack.extraData.discordUrl = Json::ensureString(obj, "discord_url"); - if(pack.extraData.discordUrl.endsWith('/')) + if (pack.extraData.discordUrl.endsWith('/')) pack.extraData.discordUrl.chop(1); auto donate_arr = Json::ensureArray(obj, "donation_urls"); - for(auto d : donate_arr){ + for (auto d : donate_arr) { auto d_obj = Json::requireObject(d); ModPlatform::DonationData donate; @@ -104,7 +104,7 @@ void Modrinth::loadIndexedPackVersions(ModPlatform::IndexedPack& pack, auto obj = versionIter.toObject(); auto file = loadIndexedPackVersion(obj); - if(file.fileId.isValid()) // Heuristic to check if the returned value is valid + if (file.fileId.isValid()) // Heuristic to check if the returned value is valid unsortedVersions.append(file); } auto orderSortPredicate = [](const ModPlatform::IndexedVersion& a, const ModPlatform::IndexedVersion& b) -> bool { @@ -116,7 +116,8 @@ void Modrinth::loadIndexedPackVersions(ModPlatform::IndexedPack& pack, pack.versionsLoaded = true; } -auto Modrinth::loadIndexedPackVersion(QJsonObject &obj, QString preferred_hash_type, QString preferred_file_name) -> ModPlatform::IndexedVersion +auto Modrinth::loadIndexedPackVersion(QJsonObject& obj, QString preferred_hash_type, QString preferred_file_name) + -> ModPlatform::IndexedVersion { ModPlatform::IndexedVersion file; @@ -141,6 +142,12 @@ auto Modrinth::loadIndexedPackVersion(QJsonObject &obj, QString preferred_hash_t auto files = Json::requireArray(obj, "files"); int i = 0; + if (files.empty()) { + // This should not happen normally, but check just in case + qWarning() << "Modrinth returned an unexpected empty list of files:" << obj; + return {}; + } + // Find correct file (needed in cases where one version may have multiple files) // Will default to the last one if there's no primary (though I think Modrinth requires that // at least one file is primary, idk) @@ -167,7 +174,7 @@ auto Modrinth::loadIndexedPackVersion(QJsonObject &obj, QString preferred_hash_t file.fileName = Json::requireString(parent, "filename"); file.is_preferred = Json::requireBoolean(parent, "primary") || (files.count() == 1); auto hash_list = Json::requireObject(parent, "hashes"); - + if (hash_list.contains(preferred_hash_type)) { file.hash = Json::requireString(hash_list, preferred_hash_type); file.hash_type = preferred_hash_type; diff --git a/launcher/resources/OSX/OSX.qrc b/launcher/resources/OSX/OSX.qrc index 55be28b5f..19fe312b6 100644 --- a/launcher/resources/OSX/OSX.qrc +++ b/launcher/resources/OSX/OSX.qrc @@ -38,5 +38,6 @@ scalable/tag.svg scalable/export.svg scalable/rename.svg + scalable/launch.svg diff --git a/launcher/resources/OSX/scalable/launch.svg b/launcher/resources/OSX/scalable/launch.svg new file mode 100644 index 000000000..fb1891625 --- /dev/null +++ b/launcher/resources/OSX/scalable/launch.svg @@ -0,0 +1,33 @@ + + + + diff --git a/launcher/resources/OSX/scalable/launcher.svg b/launcher/resources/OSX/scalable/launcher.svg index 69dd84b17..aeee84338 100644 --- a/launcher/resources/OSX/scalable/launcher.svg +++ b/launcher/resources/OSX/scalable/launcher.svg @@ -37,17 +37,21 @@ https://github.com/PrismLauncher/PrismLauncher - - - CC BY-SA 4.0 - - Prism Launcher + + + + + + + + + diff --git a/launcher/resources/backgrounds/backgrounds.qrc b/launcher/resources/backgrounds/backgrounds.qrc index 52921512a..fb4267070 100644 --- a/launcher/resources/backgrounds/backgrounds.qrc +++ b/launcher/resources/backgrounds/backgrounds.qrc @@ -1,8 +1,14 @@ - catbgrnd2.png - catmas.png - cattiversary.png + kitteh.png + kitteh-xmas.png + kitteh-bday.png + rory.png + rory-xmas.png + rory-bday.png + rory-flat.png + rory-flat-xmas.png + rory-flat-bday.png diff --git a/launcher/resources/backgrounds/cattiversary.png b/launcher/resources/backgrounds/kitteh-bday.png similarity index 100% rename from launcher/resources/backgrounds/cattiversary.png rename to launcher/resources/backgrounds/kitteh-bday.png diff --git a/launcher/resources/backgrounds/catmas.png b/launcher/resources/backgrounds/kitteh-xmas.png similarity index 100% rename from launcher/resources/backgrounds/catmas.png rename to launcher/resources/backgrounds/kitteh-xmas.png diff --git a/launcher/resources/backgrounds/catbgrnd2.png b/launcher/resources/backgrounds/kitteh.png similarity index 100% rename from launcher/resources/backgrounds/catbgrnd2.png rename to launcher/resources/backgrounds/kitteh.png diff --git a/launcher/resources/backgrounds/rory-bday.png b/launcher/resources/backgrounds/rory-bday.png new file mode 100644 index 000000000..66b880948 Binary files /dev/null and b/launcher/resources/backgrounds/rory-bday.png differ diff --git a/launcher/resources/backgrounds/rory-flat-bday.png b/launcher/resources/backgrounds/rory-flat-bday.png new file mode 100644 index 000000000..8a6e366db Binary files /dev/null and b/launcher/resources/backgrounds/rory-flat-bday.png differ diff --git a/launcher/resources/backgrounds/rory-flat-xmas.png b/launcher/resources/backgrounds/rory-flat-xmas.png new file mode 100644 index 000000000..96c3ae381 Binary files /dev/null and b/launcher/resources/backgrounds/rory-flat-xmas.png differ diff --git a/launcher/resources/backgrounds/rory-flat.png b/launcher/resources/backgrounds/rory-flat.png new file mode 100644 index 000000000..ccec0662b Binary files /dev/null and b/launcher/resources/backgrounds/rory-flat.png differ diff --git a/launcher/resources/backgrounds/rory-xmas.png b/launcher/resources/backgrounds/rory-xmas.png new file mode 100644 index 000000000..107feb780 Binary files /dev/null and b/launcher/resources/backgrounds/rory-xmas.png differ diff --git a/launcher/resources/backgrounds/rory.png b/launcher/resources/backgrounds/rory.png new file mode 100644 index 000000000..577f4dce9 Binary files /dev/null and b/launcher/resources/backgrounds/rory.png differ diff --git a/launcher/resources/flat/flat.qrc b/launcher/resources/flat/flat.qrc index 7f59da7b8..508e0a9f5 100644 --- a/launcher/resources/flat/flat.qrc +++ b/launcher/resources/flat/flat.qrc @@ -46,5 +46,6 @@ scalable/tag.svg scalable/export.svg scalable/rename.svg + scalable/launch.svg diff --git a/launcher/resources/flat/scalable/launch.svg b/launcher/resources/flat/scalable/launch.svg new file mode 100644 index 000000000..b462f2e45 --- /dev/null +++ b/launcher/resources/flat/scalable/launch.svg @@ -0,0 +1,16 @@ + + + + + diff --git a/launcher/resources/flat/scalable/launcher.svg b/launcher/resources/flat/scalable/launcher.svg index 69dd84b17..aeee84338 100644 --- a/launcher/resources/flat/scalable/launcher.svg +++ b/launcher/resources/flat/scalable/launcher.svg @@ -37,17 +37,21 @@ https://github.com/PrismLauncher/PrismLauncher - - - CC BY-SA 4.0 - - Prism Launcher + + + + + + + + + diff --git a/launcher/resources/flat_white/flat_white.qrc b/launcher/resources/flat_white/flat_white.qrc new file mode 100644 index 000000000..e11d63165 --- /dev/null +++ b/launcher/resources/flat_white/flat_white.qrc @@ -0,0 +1,51 @@ + + + + index.theme + scalable/about.svg + scalable/accounts.svg + scalable/bug.svg + scalable/cat.svg + scalable/centralmods.svg + scalable/checkupdate.svg + scalable/copy.svg + scalable/coremods.svg + scalable/custom-commands.svg + scalable/discord.svg + scalable/externaltools.svg + scalable/help.svg + scalable/instance-settings.svg + scalable/jarmods.svg + scalable/java.svg + scalable/language.svg + scalable/launcher.svg + scalable/loadermods.svg + scalable/log.svg + scalable/minecraft.svg + scalable/new.svg + scalable/news.svg + scalable/notes.svg + scalable/packages.svg + scalable/proxy.svg + scalable/quickmods.svg + scalable/reddit-alien.svg + scalable/refresh.svg + scalable/resourcepacks.svg + scalable/shaderpacks.svg + scalable/screenshot-placeholder.svg + scalable/screenshots.svg + scalable/settings.svg + scalable/star.svg + scalable/status-bad.svg + scalable/status-good.svg + scalable/status-running.svg + scalable/status-yellow.svg + scalable/viewfolder.svg + scalable/worlds.svg + scalable/delete.svg + scalable/export.svg + scalable/rename.svg + scalable/tag.svg + scalable/launch.svg + + diff --git a/launcher/resources/flat_white/index.theme b/launcher/resources/flat_white/index.theme new file mode 100644 index 000000000..54dd0e102 --- /dev/null +++ b/launcher/resources/flat_white/index.theme @@ -0,0 +1,11 @@ +[Icon Theme] +Name=Flat (White) +Comment=White version of the flat icons (dark mode) +Inherits=multimc +Directories=scalable + +[scalable] +Size=48 +Type=Scalable +MinSize=16 +MaxSize=256 diff --git a/launcher/resources/flat_white/scalable/about.svg b/launcher/resources/flat_white/scalable/about.svg new file mode 100644 index 000000000..e42ca9481 --- /dev/null +++ b/launcher/resources/flat_white/scalable/about.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/accounts.svg b/launcher/resources/flat_white/scalable/accounts.svg new file mode 100644 index 000000000..e714bde13 --- /dev/null +++ b/launcher/resources/flat_white/scalable/accounts.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/bug.svg b/launcher/resources/flat_white/scalable/bug.svg new file mode 100644 index 000000000..3122702e3 --- /dev/null +++ b/launcher/resources/flat_white/scalable/bug.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/cat.svg b/launcher/resources/flat_white/scalable/cat.svg new file mode 100644 index 000000000..18da097a7 --- /dev/null +++ b/launcher/resources/flat_white/scalable/cat.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/centralmods.svg b/launcher/resources/flat_white/scalable/centralmods.svg new file mode 100644 index 000000000..d8d10f2f5 --- /dev/null +++ b/launcher/resources/flat_white/scalable/centralmods.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/checkupdate.svg b/launcher/resources/flat_white/scalable/checkupdate.svg new file mode 100644 index 000000000..0fa66fc2f --- /dev/null +++ b/launcher/resources/flat_white/scalable/checkupdate.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/copy.svg b/launcher/resources/flat_white/scalable/copy.svg new file mode 100644 index 000000000..1aaed97b1 --- /dev/null +++ b/launcher/resources/flat_white/scalable/copy.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/coremods.svg b/launcher/resources/flat_white/scalable/coremods.svg new file mode 100644 index 000000000..32c343839 --- /dev/null +++ b/launcher/resources/flat_white/scalable/coremods.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/custom-commands.svg b/launcher/resources/flat_white/scalable/custom-commands.svg new file mode 100644 index 000000000..3d67d8f10 --- /dev/null +++ b/launcher/resources/flat_white/scalable/custom-commands.svg @@ -0,0 +1,86 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/launcher/resources/flat_white/scalable/delete.svg b/launcher/resources/flat_white/scalable/delete.svg new file mode 100644 index 000000000..3365a96f8 --- /dev/null +++ b/launcher/resources/flat_white/scalable/delete.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/discord.svg b/launcher/resources/flat_white/scalable/discord.svg new file mode 100644 index 000000000..ee07ed25e --- /dev/null +++ b/launcher/resources/flat_white/scalable/discord.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/export.svg b/launcher/resources/flat_white/scalable/export.svg new file mode 100644 index 000000000..a28bb2540 --- /dev/null +++ b/launcher/resources/flat_white/scalable/export.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/externaltools.svg b/launcher/resources/flat_white/scalable/externaltools.svg new file mode 100644 index 000000000..e7c0930c9 --- /dev/null +++ b/launcher/resources/flat_white/scalable/externaltools.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/help.svg b/launcher/resources/flat_white/scalable/help.svg new file mode 100644 index 000000000..82b413fe5 --- /dev/null +++ b/launcher/resources/flat_white/scalable/help.svg @@ -0,0 +1,17 @@ + + + + diff --git a/launcher/resources/flat_white/scalable/instance-settings.svg b/launcher/resources/flat_white/scalable/instance-settings.svg new file mode 100644 index 000000000..7dac7b141 --- /dev/null +++ b/launcher/resources/flat_white/scalable/instance-settings.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/jarmods.svg b/launcher/resources/flat_white/scalable/jarmods.svg new file mode 100644 index 000000000..f0f298f32 --- /dev/null +++ b/launcher/resources/flat_white/scalable/jarmods.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/java.svg b/launcher/resources/flat_white/scalable/java.svg new file mode 100644 index 000000000..56bb481f2 --- /dev/null +++ b/launcher/resources/flat_white/scalable/java.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/language.svg b/launcher/resources/flat_white/scalable/language.svg new file mode 100644 index 000000000..18c22efb5 --- /dev/null +++ b/launcher/resources/flat_white/scalable/language.svg @@ -0,0 +1,103 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/launcher/resources/flat_white/scalable/launch.svg b/launcher/resources/flat_white/scalable/launch.svg new file mode 100644 index 000000000..9e7594318 --- /dev/null +++ b/launcher/resources/flat_white/scalable/launch.svg @@ -0,0 +1,16 @@ + + + + + diff --git a/launcher/resources/flat_white/scalable/launcher.svg b/launcher/resources/flat_white/scalable/launcher.svg new file mode 100644 index 000000000..d7ad0dd3f --- /dev/null +++ b/launcher/resources/flat_white/scalable/launcher.svg @@ -0,0 +1,2 @@ + + diff --git a/launcher/resources/flat_white/scalable/loadermods.svg b/launcher/resources/flat_white/scalable/loadermods.svg new file mode 100644 index 000000000..100f7a93e --- /dev/null +++ b/launcher/resources/flat_white/scalable/loadermods.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/log.svg b/launcher/resources/flat_white/scalable/log.svg new file mode 100644 index 000000000..69b7c1dcc --- /dev/null +++ b/launcher/resources/flat_white/scalable/log.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/minecraft.svg b/launcher/resources/flat_white/scalable/minecraft.svg new file mode 100644 index 000000000..a0348e797 --- /dev/null +++ b/launcher/resources/flat_white/scalable/minecraft.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/multimc.svg b/launcher/resources/flat_white/scalable/multimc.svg new file mode 100644 index 000000000..3dce2699b --- /dev/null +++ b/launcher/resources/flat_white/scalable/multimc.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/new.svg b/launcher/resources/flat_white/scalable/new.svg new file mode 100644 index 000000000..46dc3361a --- /dev/null +++ b/launcher/resources/flat_white/scalable/new.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/news.svg b/launcher/resources/flat_white/scalable/news.svg new file mode 100644 index 000000000..414e54540 --- /dev/null +++ b/launcher/resources/flat_white/scalable/news.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/notes.svg b/launcher/resources/flat_white/scalable/notes.svg new file mode 100644 index 000000000..4ce5f6f19 --- /dev/null +++ b/launcher/resources/flat_white/scalable/notes.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/packages.svg b/launcher/resources/flat_white/scalable/packages.svg new file mode 100644 index 000000000..909ad0b27 --- /dev/null +++ b/launcher/resources/flat_white/scalable/packages.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/patreon.svg b/launcher/resources/flat_white/scalable/patreon.svg new file mode 100644 index 000000000..b745765b4 --- /dev/null +++ b/launcher/resources/flat_white/scalable/patreon.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/proxy.svg b/launcher/resources/flat_white/scalable/proxy.svg new file mode 100644 index 000000000..a86703f45 --- /dev/null +++ b/launcher/resources/flat_white/scalable/proxy.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/quickmods.svg b/launcher/resources/flat_white/scalable/quickmods.svg new file mode 100644 index 000000000..9e0045b20 --- /dev/null +++ b/launcher/resources/flat_white/scalable/quickmods.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/reddit-alien.svg b/launcher/resources/flat_white/scalable/reddit-alien.svg new file mode 100644 index 000000000..be22148ca --- /dev/null +++ b/launcher/resources/flat_white/scalable/reddit-alien.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/refresh.svg b/launcher/resources/flat_white/scalable/refresh.svg new file mode 100644 index 000000000..08c63bdf7 --- /dev/null +++ b/launcher/resources/flat_white/scalable/refresh.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/rename.svg b/launcher/resources/flat_white/scalable/rename.svg new file mode 100644 index 000000000..f2067c16b --- /dev/null +++ b/launcher/resources/flat_white/scalable/rename.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/resourcepacks.svg b/launcher/resources/flat_white/scalable/resourcepacks.svg new file mode 100644 index 000000000..9dd73c3af --- /dev/null +++ b/launcher/resources/flat_white/scalable/resourcepacks.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/screenshot-placeholder.svg b/launcher/resources/flat_white/scalable/screenshot-placeholder.svg new file mode 100644 index 000000000..41eb6fcfc --- /dev/null +++ b/launcher/resources/flat_white/scalable/screenshot-placeholder.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/screenshots.svg b/launcher/resources/flat_white/scalable/screenshots.svg new file mode 100644 index 000000000..68cf89696 --- /dev/null +++ b/launcher/resources/flat_white/scalable/screenshots.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/settings.svg b/launcher/resources/flat_white/scalable/settings.svg new file mode 100644 index 000000000..7dac7b141 --- /dev/null +++ b/launcher/resources/flat_white/scalable/settings.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/shaderpacks.svg b/launcher/resources/flat_white/scalable/shaderpacks.svg new file mode 100644 index 000000000..ccae221c1 --- /dev/null +++ b/launcher/resources/flat_white/scalable/shaderpacks.svg @@ -0,0 +1,56 @@ + + + + + + + + + + + diff --git a/launcher/resources/flat_white/scalable/star.svg b/launcher/resources/flat_white/scalable/star.svg new file mode 100644 index 000000000..116f952eb --- /dev/null +++ b/launcher/resources/flat_white/scalable/star.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/status-bad.svg b/launcher/resources/flat_white/scalable/status-bad.svg new file mode 100644 index 000000000..5a121c09c --- /dev/null +++ b/launcher/resources/flat_white/scalable/status-bad.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/status-good.svg b/launcher/resources/flat_white/scalable/status-good.svg new file mode 100644 index 000000000..ccb732ab8 --- /dev/null +++ b/launcher/resources/flat_white/scalable/status-good.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/status-running.svg b/launcher/resources/flat_white/scalable/status-running.svg new file mode 100644 index 000000000..aa2d5fbff --- /dev/null +++ b/launcher/resources/flat_white/scalable/status-running.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/status-yellow.svg b/launcher/resources/flat_white/scalable/status-yellow.svg new file mode 100644 index 000000000..772699d32 --- /dev/null +++ b/launcher/resources/flat_white/scalable/status-yellow.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/tag.svg b/launcher/resources/flat_white/scalable/tag.svg new file mode 100644 index 000000000..f91fb0b42 --- /dev/null +++ b/launcher/resources/flat_white/scalable/tag.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/viewfolder.svg b/launcher/resources/flat_white/scalable/viewfolder.svg new file mode 100644 index 000000000..145f86248 --- /dev/null +++ b/launcher/resources/flat_white/scalable/viewfolder.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/worlds.svg b/launcher/resources/flat_white/scalable/worlds.svg new file mode 100644 index 000000000..cea30cf81 --- /dev/null +++ b/launcher/resources/flat_white/scalable/worlds.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/iOS/iOS.qrc b/launcher/resources/iOS/iOS.qrc index 1d7520420..aa08d811a 100644 --- a/launcher/resources/iOS/iOS.qrc +++ b/launcher/resources/iOS/iOS.qrc @@ -38,5 +38,6 @@ scalable/tag.svg scalable/export.svg scalable/rename.svg + scalable/launch.svg diff --git a/launcher/resources/iOS/scalable/launch.svg b/launcher/resources/iOS/scalable/launch.svg new file mode 100644 index 000000000..c16d5c37c --- /dev/null +++ b/launcher/resources/iOS/scalable/launch.svg @@ -0,0 +1,17 @@ + + + + diff --git a/launcher/resources/iOS/scalable/launcher.svg b/launcher/resources/iOS/scalable/launcher.svg index 69dd84b17..aeee84338 100644 --- a/launcher/resources/iOS/scalable/launcher.svg +++ b/launcher/resources/iOS/scalable/launcher.svg @@ -37,17 +37,21 @@ https://github.com/PrismLauncher/PrismLauncher - - - CC BY-SA 4.0 - - Prism Launcher + + + + + + + + + diff --git a/launcher/resources/multimc/scalable/launcher.svg b/launcher/resources/multimc/scalable/launcher.svg index 69dd84b17..aeee84338 100644 --- a/launcher/resources/multimc/scalable/launcher.svg +++ b/launcher/resources/multimc/scalable/launcher.svg @@ -37,17 +37,21 @@ https://github.com/PrismLauncher/PrismLauncher - - - CC BY-SA 4.0 - - Prism Launcher + + + + + + + + + diff --git a/launcher/resources/pe_blue/pe_blue.qrc b/launcher/resources/pe_blue/pe_blue.qrc index 3d3857133..3121ffe6b 100644 --- a/launcher/resources/pe_blue/pe_blue.qrc +++ b/launcher/resources/pe_blue/pe_blue.qrc @@ -38,5 +38,6 @@ scalable/tag.svg scalable/export.svg scalable/rename.svg + scalable/launch.svg diff --git a/launcher/resources/pe_blue/scalable/launch.svg b/launcher/resources/pe_blue/scalable/launch.svg new file mode 100644 index 000000000..b3bd124f4 --- /dev/null +++ b/launcher/resources/pe_blue/scalable/launch.svg @@ -0,0 +1,20 @@ + + + + diff --git a/launcher/resources/pe_blue/scalable/launcher.svg b/launcher/resources/pe_blue/scalable/launcher.svg index 69dd84b17..aeee84338 100644 --- a/launcher/resources/pe_blue/scalable/launcher.svg +++ b/launcher/resources/pe_blue/scalable/launcher.svg @@ -37,17 +37,21 @@ https://github.com/PrismLauncher/PrismLauncher - - - CC BY-SA 4.0 - - Prism Launcher + + + + + + + + + diff --git a/launcher/resources/pe_colored/pe_colored.qrc b/launcher/resources/pe_colored/pe_colored.qrc index fa6cd9cd4..ce5ad8e21 100644 --- a/launcher/resources/pe_colored/pe_colored.qrc +++ b/launcher/resources/pe_colored/pe_colored.qrc @@ -38,5 +38,6 @@ scalable/tag.svg scalable/export.svg scalable/rename.svg + scalable/launch.svg diff --git a/launcher/resources/pe_colored/scalable/launch.svg b/launcher/resources/pe_colored/scalable/launch.svg new file mode 100644 index 000000000..76713387d --- /dev/null +++ b/launcher/resources/pe_colored/scalable/launch.svg @@ -0,0 +1,23 @@ + + + + diff --git a/launcher/resources/pe_colored/scalable/launcher.svg b/launcher/resources/pe_colored/scalable/launcher.svg index 69dd84b17..aeee84338 100644 --- a/launcher/resources/pe_colored/scalable/launcher.svg +++ b/launcher/resources/pe_colored/scalable/launcher.svg @@ -37,17 +37,21 @@ https://github.com/PrismLauncher/PrismLauncher - - - CC BY-SA 4.0 - - Prism Launcher + + + + + + + + + diff --git a/launcher/resources/pe_dark/pe_dark.qrc b/launcher/resources/pe_dark/pe_dark.qrc index 6b9c7cb60..156d8f8b4 100644 --- a/launcher/resources/pe_dark/pe_dark.qrc +++ b/launcher/resources/pe_dark/pe_dark.qrc @@ -38,5 +38,6 @@ scalable/tag.svg scalable/export.svg scalable/rename.svg + scalable/launch.svg diff --git a/launcher/resources/pe_dark/scalable/launch.svg b/launcher/resources/pe_dark/scalable/launch.svg new file mode 100644 index 000000000..3746e2dd6 --- /dev/null +++ b/launcher/resources/pe_dark/scalable/launch.svg @@ -0,0 +1,17 @@ + + + + diff --git a/launcher/resources/pe_dark/scalable/launcher.svg b/launcher/resources/pe_dark/scalable/launcher.svg index 69dd84b17..aeee84338 100644 --- a/launcher/resources/pe_dark/scalable/launcher.svg +++ b/launcher/resources/pe_dark/scalable/launcher.svg @@ -37,17 +37,21 @@ https://github.com/PrismLauncher/PrismLauncher - - - CC BY-SA 4.0 - - Prism Launcher + + + + + + + + + diff --git a/launcher/resources/pe_light/pe_light.qrc b/launcher/resources/pe_light/pe_light.qrc index 963bfcdeb..d8e4a1bd7 100644 --- a/launcher/resources/pe_light/pe_light.qrc +++ b/launcher/resources/pe_light/pe_light.qrc @@ -38,5 +38,6 @@ scalable/tag.svg scalable/export.svg scalable/rename.svg + scalable/launch.svg diff --git a/launcher/resources/pe_light/scalable/launch.svg b/launcher/resources/pe_light/scalable/launch.svg new file mode 100644 index 000000000..6c27b7e0c --- /dev/null +++ b/launcher/resources/pe_light/scalable/launch.svg @@ -0,0 +1,17 @@ + + + + diff --git a/launcher/resources/pe_light/scalable/launcher.svg b/launcher/resources/pe_light/scalable/launcher.svg index 69dd84b17..aeee84338 100644 --- a/launcher/resources/pe_light/scalable/launcher.svg +++ b/launcher/resources/pe_light/scalable/launcher.svg @@ -37,17 +37,21 @@ https://github.com/PrismLauncher/PrismLauncher - - - CC BY-SA 4.0 - - Prism Launcher + + + + + + + + + diff --git a/launcher/tasks/Task.cpp b/launcher/tasks/Task.cpp index b4babdd4f..9ea1bb26d 100644 --- a/launcher/tasks/Task.cpp +++ b/launcher/tasks/Task.cpp @@ -153,7 +153,7 @@ QString Task::describe() auto name = objectName(); if(name.isEmpty()) { - out << QString("0x%1").arg((quintptr)this, 0, 16); + out << QString("0x%1").arg(reinterpret_cast(this), 0, 16); } else { diff --git a/launcher/translations/TranslationsModel.cpp b/launcher/translations/TranslationsModel.cpp index 2f57de3a9..20aa6d040 100644 --- a/launcher/translations/TranslationsModel.cpp +++ b/launcher/translations/TranslationsModel.cpp @@ -83,6 +83,12 @@ struct Language else if(key == "es_UY") { result = u8"español de Latinoamérica"; } + else if(key == "en@pirate") { + result = u8"Tongue of the High Seas"; + } + else if(key == "en@uwu") { + result = u8"Cute Engwish"; + } else { result = locale.nativeLanguageName(); } diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 97152a485..28eaa741b 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -335,11 +335,10 @@ public: all_actions.append(&actionSettings); actionUndoTrashInstance = TranslatedAction(MainWindow); - connect(actionUndoTrashInstance, SIGNAL(triggered(bool)), MainWindow, SLOT(undoTrashInstance())); actionUndoTrashInstance->setObjectName(QStringLiteral("actionUndoTrashInstance")); actionUndoTrashInstance.setTextId(QT_TRANSLATE_NOOP("MainWindow", "&Undo Last Instance Deletion")); actionUndoTrashInstance->setEnabled(APPLICATION->instances()->trashedSomething()); - actionUndoTrashInstance->setShortcut(QKeySequence("Ctrl+Z")); + actionUndoTrashInstance->setShortcut(QKeySequence::Undo); all_actions.append(&actionUndoTrashInstance); actionClearMetadata = TranslatedAction(MainWindow); @@ -527,7 +526,7 @@ public: menuBar->addMenu(foldersMenu); - profileMenu = menuBar->addMenu(tr("&Profiles")); + profileMenu = menuBar->addMenu(tr("&Accounts")); profileMenu->setSeparatorsCollapsible(false); profileMenu->addAction(actionManageAccounts); @@ -656,6 +655,7 @@ public: actionLaunchInstance->setObjectName(QStringLiteral("actionLaunchInstance")); actionLaunchInstance.setTextId(QT_TRANSLATE_NOOP("MainWindow", "&Launch")); actionLaunchInstance.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Launch the selected instance.")); + actionLaunchInstance->setIcon(APPLICATION->getThemedIcon("launch")); all_actions.append(&actionLaunchInstance); actionLaunchInstanceOffline = TranslatedAction(MainWindow); @@ -741,7 +741,9 @@ public: // See https://github.com/PolyMC/PolyMC/issues/493 connect(instanceToolBar, &QToolBar::orientationChanged, [=](Qt::Orientation){ instanceToolBar->setOrientation(Qt::Vertical); }); instanceToolBar->setAllowedAreas(Qt::LeftToolBarArea | Qt::RightToolBarArea); - instanceToolBar->setToolButtonStyle(Qt::ToolButtonTextOnly); + instanceToolBar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + instanceToolBar->setIconSize(QSize(16, 16)); + instanceToolBar->setFloatable(false); instanceToolBar->setWindowTitle(QT_TRANSLATE_NOOP("MainWindow", "Instance Toolbar")); @@ -761,8 +763,18 @@ public: instanceToolBar->addAction(actionViewSelectedInstFolder); instanceToolBar->addAction(actionExportInstance); - instanceToolBar->addAction(actionDeleteInstance); instanceToolBar->addAction(actionCopyInstance); + instanceToolBar->addAction(actionDeleteInstance); + + QLayout * lay = instanceToolBar->layout(); + for(int i = 0; i < lay->count(); i++) + { + QLayoutItem * item = lay->itemAt(i); + if (item->widget()->metaObject()->className() == QString("QToolButton")) + { + item->setAlignment(Qt::AlignLeft); + } + } all_toolbars.append(&instanceToolBar); MainWindow->addToolBar(Qt::RightToolBarArea, instanceToolBar); @@ -1010,6 +1022,8 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new MainWindow } } + connect(ui->actionUndoTrashInstance.operator->(), &QAction::triggered, this, &MainWindow::undoTrashInstance); + setSelectedInstanceById(APPLICATION->settings()->get("SelectedInstance").toString()); // removing this looks stupid @@ -1039,7 +1053,7 @@ void MainWindow::retranslateUi() accountMenuButton->setText(profileLabel); } else { - accountMenuButton->setText(tr("Profiles")); + accountMenuButton->setText(tr("Accounts")); } if (m_selectedInstance) { @@ -1121,11 +1135,6 @@ void MainWindow::showInstanceContextMenu(const QPoint &pos) connect(actionDeleteGroup, SIGNAL(triggered(bool)), SLOT(deleteGroup())); actions.append(actionDeleteGroup); } - - QAction *actionUndoTrashInstance = new QAction("Undo last trash instance", this); - connect(actionUndoTrashInstance, SIGNAL(triggered(bool)), SLOT(undoTrashInstance())); - actionUndoTrashInstance->setEnabled(APPLICATION->instances()->trashedSomething()); - actions.append(actionUndoTrashInstance); } QMenu myMenu; myMenu.addActions(actions); @@ -1382,7 +1391,7 @@ void MainWindow::defaultAccountChanged() // Set the icon to the "no account" icon. accountMenuButton->setIcon(APPLICATION->getThemedIcon("noaccount")); - accountMenuButton->setText(tr("Profiles")); + accountMenuButton->setText(tr("Accounts")); } bool MainWindow::eventFilter(QObject *obj, QEvent *ev) @@ -1551,15 +1560,13 @@ void MainWindow::setCatBackground(bool enabled) QDateTime now = QDateTime::currentDateTime(); QDateTime birthday(QDate(now.date().year(), 11, 30), QTime(0, 0)); QDateTime xmas(QDate(now.date().year(), 12, 25), QTime(0, 0)); - QString cat; + QString cat = APPLICATION->settings()->get("BackgroundCat").toString(); + if(non_stupid_abs(now.daysTo(xmas)) <= 4) { - cat = "catmas"; + cat += "-xmas"; } else if (non_stupid_abs(now.daysTo(birthday)) <= 12) { - cat = "cattiversary"; - } - else { - cat = "kitteh"; + cat += "-bday"; } view->setStyleSheet(QString(R"( InstanceView @@ -1567,10 +1574,11 @@ InstanceView background-image: url(:/backgrounds/%1); background-attachment: fixed; background-clip: padding; - background-position: top right; + background-position: bottom left; background-repeat: none; background-color:palette(base); -})").arg(cat)); +})") + .arg(cat)); } else { @@ -1821,6 +1829,7 @@ void MainWindow::deleteGroup() void MainWindow::undoTrashInstance() { APPLICATION->instances()->undoTrashInstance(); + ui->actionUndoTrashInstance->setEnabled(APPLICATION->instances()->trashedSomething()); } void MainWindow::on_actionViewInstanceFolder_triggered() @@ -1927,6 +1936,7 @@ void MainWindow::on_actionDeleteInstance_triggered() auto id = m_selectedInstance->id(); if (APPLICATION->instances()->trashInstance(id)) { + ui->actionUndoTrashInstance->setEnabled(APPLICATION->instances()->trashedSomething()); return; } diff --git a/launcher/ui/dialogs/AboutDialog.cpp b/launcher/ui/dialogs/AboutDialog.cpp index cecda1df5..a36e4a3dd 100644 --- a/launcher/ui/dialogs/AboutDialog.cpp +++ b/launcher/ui/dialogs/AboutDialog.cpp @@ -73,17 +73,12 @@ QString getCreditsHtml() stream << "

" << QObject::tr("%1 Developers", "About Credits").arg(BuildConfig.LAUNCHER_DISPLAYNAME) << "

\n"; stream << QString("

Sefa Eyeoglu (Scrumplex) %1

\n") .arg(getWebsite("https://scrumplex.net")); stream << QString("

dada513 %1

\n") .arg(getGitHub("dada513")); - stream << QString("

txtsd %1

\n") .arg(getGitHub("txtsd")); + stream << QString("

txtsd %1

\n") .arg(getWebsite("https://ihavea.quest")); stream << QString("

timoreo %1

\n") .arg(getGitHub("timoreo22")); stream << QString("

Ezekiel Smith (ZekeSmith) %1

\n") .arg(getGitHub("ZekeSmith")); stream << QString("

cozyGalvinism %1

\n") .arg(getGitHub("cozyGalvinism")); - stream << "
\n"; - - //: %1 is the name of the launcher, determined at build time, e.g. "Prism Launcher Contributors" - stream << "

" << QObject::tr("%1 Contributors", "About Credits").arg(BuildConfig.LAUNCHER_DISPLAYNAME) << "

\n"; stream << QString("

DioEgizio %1

\n") .arg(getGitHub("DioEgizio")); stream << QString("

flowln %1

\n") .arg(getGitHub("flowln")); - stream << QString("

swirl %1

\n") .arg(getWebsite("https://swurl.xyz/")); stream << "
\n"; // TODO: possibly retrieve from git history at build time? @@ -97,7 +92,7 @@ QString getCreditsHtml() stream << "
\n"; stream << "

" << QObject::tr("With thanks to", "About Credits") << "

\n"; - stream << QString("

Boba %1

\n") .arg(getWebsite("https://cmdplusv.neocities.org/")); + stream << QString("

Boba %1

\n") .arg(getWebsite("https://bobaonline.neocities.org/")); stream << QString("

Davi Rafael %1

\n") .arg(getWebsite("https://auti.one/")); stream << QString("

Fulmine %1

\n") .arg(getWebsite("https://www.fulmine.xyz/")); stream << QString("

ely %1

\n") .arg(getGitHub("elyrodso")); diff --git a/launcher/ui/dialogs/AboutDialog.ui b/launcher/ui/dialogs/AboutDialog.ui index e0429321e..4a9eef08f 100644 --- a/launcher/ui/dialogs/AboutDialog.ui +++ b/launcher/ui/dialogs/AboutDialog.ui @@ -87,14 +87,11 @@ - + IBeamCursor - - Qt::AlignCenter - Qt::TextSelectableByMouse @@ -167,7 +164,7 @@ - + IBeamCursor @@ -183,7 +180,7 @@ - + IBeamCursor @@ -199,7 +196,7 @@ - + IBeamCursor @@ -215,7 +212,7 @@ - + IBeamCursor diff --git a/launcher/ui/dialogs/ModUpdateDialog.cpp b/launcher/ui/dialogs/ModUpdateDialog.cpp index 4171586e9..cedd4a96e 100644 --- a/launcher/ui/dialogs/ModUpdateDialog.cpp +++ b/launcher/ui/dialogs/ModUpdateDialog.cpp @@ -366,33 +366,28 @@ void ModUpdateDialog::appendMod(CheckUpdateTask::UpdatableMod const& info) auto changelog = new QTreeWidgetItem(changelog_item); auto changelog_area = new QTextBrowser(); + QString text = info.changelog; switch (info.provider) { case ModPlatform::Provider::MODRINTH: { HoeDown h; // HoeDown bug?: \n aren't converted to
- auto text = h.process(info.changelog.toUtf8()); + text = h.process(info.changelog.toUtf8()); // Don't convert if there's an HTML tag right after (Qt rendering weirdness) text.remove(QRegularExpression("(\n+)(?=<)")); text.replace('\n', "
"); - changelog_area->setHtml(text); break; } - case ModPlatform::Provider::FLAME: { - changelog_area->setHtml(info.changelog); + default: break; - } } + changelog_area->setHtml(text); changelog_area->setOpenExternalLinks(true); - changelog_area->setLineWrapMode(QTextBrowser::LineWrapMode::NoWrap); + changelog_area->setLineWrapMode(QTextBrowser::LineWrapMode::WidgetWidth); changelog_area->setVerticalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAsNeeded); - // HACK: Is there a better way of achieving this? - auto font_height = QFontMetrics(changelog_area->font()).height(); - changelog_area->setMaximumHeight((changelog_area->toPlainText().count(QRegularExpression("\n|
")) + 2) * font_height); - ui->modTreeWidget->setItemWidget(changelog, 0, changelog_area); ui->modTreeWidget->addTopLevelItem(item_top); diff --git a/launcher/ui/dialogs/ProgressDialog.cpp b/launcher/ui/dialogs/ProgressDialog.cpp index 68dd4d17e..05269f623 100644 --- a/launcher/ui/dialogs/ProgressDialog.cpp +++ b/launcher/ui/dialogs/ProgressDialog.cpp @@ -136,11 +136,13 @@ void ProgressDialog::onTaskStarted() {} void ProgressDialog::onTaskFailed(QString failure) { reject(); + hide(); } void ProgressDialog::onTaskSucceeded() { accept(); + hide(); } void ProgressDialog::changeStatus(const QString& status) diff --git a/launcher/ui/dialogs/VersionSelectDialog.cpp b/launcher/ui/dialogs/VersionSelectDialog.cpp index 70ef72d6c..d7880334f 100644 --- a/launcher/ui/dialogs/VersionSelectDialog.cpp +++ b/launcher/ui/dialogs/VersionSelectDialog.cpp @@ -120,7 +120,7 @@ void VersionSelectDialog::selectRecommended() m_versionWidget->selectRecommended(); } -BaseVersionPtr VersionSelectDialog::selectedVersion() const +BaseVersion::Ptr VersionSelectDialog::selectedVersion() const { return m_versionWidget->selectedVersion(); } diff --git a/launcher/ui/dialogs/VersionSelectDialog.h b/launcher/ui/dialogs/VersionSelectDialog.h index ed30d3f3c..18a50cdb0 100644 --- a/launcher/ui/dialogs/VersionSelectDialog.h +++ b/launcher/ui/dialogs/VersionSelectDialog.h @@ -44,7 +44,7 @@ public: int exec() override; - BaseVersionPtr selectedVersion() const; + BaseVersion::Ptr selectedVersion() const; void setCurrentVersion(const QString & version); void setFuzzyFilter(BaseVersionList::ModelRoles role, QString filter); diff --git a/launcher/ui/pages/global/APIPage.ui b/launcher/ui/pages/global/APIPage.ui index 1ae788c7f..d56a9ef68 100644 --- a/launcher/ui/pages/global/APIPage.ui +++ b/launcher/ui/pages/global/APIPage.ui @@ -179,7 +179,7 @@ - Enter a custom client ID for Microsoft Authentication here. + Enter a custom client ID for Microsoft Authentication here. Qt::RichText diff --git a/launcher/ui/pages/global/LauncherPage.cpp b/launcher/ui/pages/global/LauncherPage.cpp index b8431e8c4..822c69b0d 100644 --- a/launcher/ui/pages/global/LauncherPage.cpp +++ b/launcher/ui/pages/global/LauncherPage.cpp @@ -49,6 +49,7 @@ #include #include "Application.h" #include "BuildConfig.h" +#include "DesktopServices.h" #include "ui/themes/ITheme.h" #include @@ -143,7 +144,7 @@ void LauncherPage::on_instDirBrowseBtn_clicked() ui->instDirTextBox->setText(cooked_dir); } } - else if(APPLICATION->isFlatpak() && raw_dir.startsWith("/run/user")) + else if(DesktopServices::isFlatpak() && raw_dir.startsWith("/run/user")) { QMessageBox warning; warning.setText(tr("You're trying to specify an instance folder " @@ -310,9 +311,12 @@ void LauncherPage::applySettings() s->set("IconTheme", "flat"); break; case 7: - s->set("IconTheme", "multimc"); + s->set("IconTheme", "flat_white"); break; case 8: + s->set("IconTheme", "multimc"); + break; + case 9: s->set("IconTheme", "custom"); break; } @@ -330,6 +334,18 @@ void LauncherPage::applySettings() APPLICATION->setApplicationTheme(newAppTheme, false); } + switch (ui->themeBackgroundCat->currentIndex()) { + case 0: // original cat + s->set("BackgroundCat", "kitteh"); + break; + case 1: // rory the cat + s->set("BackgroundCat", "rory"); + break; + case 2: // rory the cat flat edition + s->set("BackgroundCat", "rory-flat"); + break; + } + s->set("MenuBarInsteadOfToolBar", ui->preferMenuBarCheckBox->isChecked()); // Console settings @@ -408,14 +424,27 @@ void LauncherPage::loadSettings() { ui->themeComboBox->setCurrentIndex(6); } - else if (theme == "multimc") + else if (theme == "flat_white") { ui->themeComboBox->setCurrentIndex(7); } - else if (theme == "custom") + else if (theme == "multimc") { ui->themeComboBox->setCurrentIndex(8); } + else if (theme == "custom") + { + ui->themeComboBox->setCurrentIndex(9); + } + + auto cat = s->get("BackgroundCat").toString(); + if (cat == "kitteh") { + ui->themeBackgroundCat->setCurrentIndex(0); + } else if (cat == "rory") { + ui->themeBackgroundCat->setCurrentIndex(1); + } else if (cat == "rory-flat") { + ui->themeBackgroundCat->setCurrentIndex(2); + } { auto currentTheme = s->get("ApplicationTheme").toString(); diff --git a/launcher/ui/pages/global/LauncherPage.ui b/launcher/ui/pages/global/LauncherPage.ui index 0d14f147f..6de644ee5 100644 --- a/launcher/ui/pages/global/LauncherPage.ui +++ b/launcher/ui/pages/global/LauncherPage.ui @@ -300,6 +300,11 @@ Flat + + + Flat (White) + + Legacy @@ -335,6 +340,44 @@
+ + + + C&at + + + themeBackgroundCat + + + + + + + + 0 + 0 + + + + Qt::StrongFocus + + + + Background Cat (from MultiMC) + + + + + Rory ID 11 (drawn by Ashtaka) + + + + + Rory ID 11 (flat edition, drawn by Ashtaka) + + + +
diff --git a/launcher/ui/pages/modplatform/ModModel.cpp b/launcher/ui/pages/modplatform/ModModel.cpp index 49766fa66..ed58eb32f 100644 --- a/launcher/ui/pages/modplatform/ModModel.cpp +++ b/launcher/ui/pages/modplatform/ModModel.cpp @@ -267,18 +267,25 @@ void ListModel::searchRequestFailed(QString reason) .arg(m_parent->displayName()) .arg(tr("API version too old!\nPlease update %1!").arg(BuildConfig.LAUNCHER_DISPLAYNAME))); } + + jobPtr.reset(); + searchState = Finished; +} + +void ListModel::searchRequestAborted() +{ + if (searchState != ResetRequested) + qCritical() << "Search task in ModModel aborted by an unknown reason!"; + + // Retry fetching jobPtr.reset(); - if (searchState == ResetRequested) { - beginResetModel(); - modpacks.clear(); - endResetModel(); + beginResetModel(); + modpacks.clear(); + endResetModel(); - nextSearchOffset = 0; - performPaginatedSearch(); - } else { - searchState = Finished; - } + nextSearchOffset = 0; + performPaginatedSearch(); } void ListModel::infoRequestFinished(QJsonDocument& doc, ModPlatform::IndexedPack& pack, const QModelIndex& index) diff --git a/launcher/ui/pages/modplatform/ModModel.h b/launcher/ui/pages/modplatform/ModModel.h index a58c7c55b..d2636d87e 100644 --- a/launcher/ui/pages/modplatform/ModModel.h +++ b/launcher/ui/pages/modplatform/ModModel.h @@ -51,6 +51,7 @@ class ListModel : public QAbstractListModel { public slots: void searchRequestFinished(QJsonDocument& doc); void searchRequestFailed(QString reason); + void searchRequestAborted(); void infoRequestFinished(QJsonDocument& doc, ModPlatform::IndexedPack& pack, const QModelIndex& index); diff --git a/launcher/ui/pages/modplatform/VanillaPage.cpp b/launcher/ui/pages/modplatform/VanillaPage.cpp index 99190f31e..29fecb854 100644 --- a/launcher/ui/pages/modplatform/VanillaPage.cpp +++ b/launcher/ui/pages/modplatform/VanillaPage.cpp @@ -187,12 +187,12 @@ void VanillaPage::retranslate() ui->retranslateUi(this); } -BaseVersionPtr VanillaPage::selectedVersion() const +BaseVersion::Ptr VanillaPage::selectedVersion() const { return m_selectedVersion; } -BaseVersionPtr VanillaPage::selectedLoaderVersion() const +BaseVersion::Ptr VanillaPage::selectedLoaderVersion() const { return m_selectedLoaderVersion; } @@ -227,14 +227,14 @@ void VanillaPage::suggestCurrent() dialog->setSuggestedIcon("default"); } -void VanillaPage::setSelectedVersion(BaseVersionPtr version) +void VanillaPage::setSelectedVersion(BaseVersion::Ptr version) { m_selectedVersion = version; suggestCurrent(); loaderFilterChanged(); } -void VanillaPage::setSelectedLoaderVersion(BaseVersionPtr version) +void VanillaPage::setSelectedLoaderVersion(BaseVersion::Ptr version) { m_selectedLoaderVersion = version; suggestCurrent(); diff --git a/launcher/ui/pages/modplatform/VanillaPage.h b/launcher/ui/pages/modplatform/VanillaPage.h index 7193597dd..39aba760b 100644 --- a/launcher/ui/pages/modplatform/VanillaPage.h +++ b/launcher/ui/pages/modplatform/VanillaPage.h @@ -76,13 +76,13 @@ public: void openedImpl() override; - BaseVersionPtr selectedVersion() const; - BaseVersionPtr selectedLoaderVersion() const; + BaseVersion::Ptr selectedVersion() const; + BaseVersion::Ptr selectedLoaderVersion() const; QString selectedLoader() const; public slots: - void setSelectedVersion(BaseVersionPtr version); - void setSelectedLoaderVersion(BaseVersionPtr version); + void setSelectedVersion(BaseVersion::Ptr version); + void setSelectedLoaderVersion(BaseVersion::Ptr version); private slots: void filterChanged(); @@ -98,7 +98,7 @@ private: NewInstanceDialog *dialog = nullptr; Ui::VanillaPage *ui = nullptr; bool m_versionSetByUser = false; - BaseVersionPtr m_selectedVersion; - BaseVersionPtr m_selectedLoaderVersion; + BaseVersion::Ptr m_selectedVersion; + BaseVersion::Ptr m_selectedLoaderVersion; QString m_selectedLoader; }; diff --git a/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp b/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp index 004fdc57a..9138dcbbb 100644 --- a/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp +++ b/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp @@ -331,7 +331,7 @@ AtlOptionalModDialog::AtlOptionalModDialog(QWidget* parent, ATLauncher::PackVers connect(ui->clearAllButton, &QPushButton::clicked, listModel, &AtlOptionalModListModel::clearAll); connect(ui->installButton, &QPushButton::clicked, - this, &QDialog::close); + this, &QDialog::accept); } AtlOptionalModDialog::~AtlOptionalModDialog() { diff --git a/launcher/ui/pages/modplatform/atlauncher/AtlUserInteractionSupportImpl.cpp b/launcher/ui/pages/modplatform/atlauncher/AtlUserInteractionSupportImpl.cpp index 031966850..f5f50caee 100644 --- a/launcher/ui/pages/modplatform/atlauncher/AtlUserInteractionSupportImpl.cpp +++ b/launcher/ui/pages/modplatform/atlauncher/AtlUserInteractionSupportImpl.cpp @@ -43,14 +43,17 @@ AtlUserInteractionSupportImpl::AtlUserInteractionSupportImpl(QWidget *parent) : { } -QVector AtlUserInteractionSupportImpl::chooseOptionalMods(ATLauncher::PackVersion version, QVector mods) +std::optional> AtlUserInteractionSupportImpl::chooseOptionalMods(ATLauncher::PackVersion version, QVector mods) { AtlOptionalModDialog optionalModDialog(m_parent, version, mods); - optionalModDialog.exec(); + auto result = optionalModDialog.exec(); + if (result == QDialog::Rejected) { + return {}; + } return optionalModDialog.getResult(); } -QString AtlUserInteractionSupportImpl::chooseVersion(Meta::VersionListPtr vlist, QString minecraftVersion) +QString AtlUserInteractionSupportImpl::chooseVersion(Meta::VersionList::Ptr vlist, QString minecraftVersion) { VersionSelectDialog vselect(vlist.get(), "Choose Version", m_parent, false); if (minecraftVersion != nullptr) { diff --git a/launcher/ui/pages/modplatform/atlauncher/AtlUserInteractionSupportImpl.h b/launcher/ui/pages/modplatform/atlauncher/AtlUserInteractionSupportImpl.h index aa22fc730..37010b3ff 100644 --- a/launcher/ui/pages/modplatform/atlauncher/AtlUserInteractionSupportImpl.h +++ b/launcher/ui/pages/modplatform/atlauncher/AtlUserInteractionSupportImpl.h @@ -46,8 +46,8 @@ public: AtlUserInteractionSupportImpl(QWidget* parent); private: - QString chooseVersion(Meta::VersionListPtr vlist, QString minecraftVersion) override; - QVector chooseOptionalMods(ATLauncher::PackVersion version, QVector mods) override; + QString chooseVersion(Meta::VersionList::Ptr vlist, QString minecraftVersion) override; + std::optional> chooseOptionalMods(ATLauncher::PackVersion version, QVector mods) override; void displayMessage(QString message) override; private: diff --git a/launcher/ui/pages/modplatform/flame/FlameModel.cpp b/launcher/ui/pages/modplatform/flame/FlameModel.cpp index b98046813..9f8605eb3 100644 --- a/launcher/ui/pages/modplatform/flame/FlameModel.cpp +++ b/launcher/ui/pages/modplatform/flame/FlameModel.cpp @@ -1,6 +1,7 @@ #include "FlameModel.h" #include #include "Application.h" +#include "ui/widgets/ProjectItem.h" #include #include @@ -31,29 +32,38 @@ QVariant ListModel::data(const QModelIndex& index, int role) const } IndexedPack pack = modpacks.at(pos); - if (role == Qt::DisplayRole) { - return pack.name; - } else if (role == Qt::ToolTipRole) { - if (pack.description.length() > 100) { - // some magic to prevent to long tooltips and replace html linebreaks - QString edit = pack.description.left(97); - edit = edit.left(edit.lastIndexOf("
")).left(edit.lastIndexOf(" ")).append("..."); - return edit; + switch (role) { + case Qt::ToolTipRole: { + if (pack.description.length() > 100) { + // some magic to prevent to long tooltips and replace html linebreaks + QString edit = pack.description.left(97); + edit = edit.left(edit.lastIndexOf("
")).left(edit.lastIndexOf(" ")).append("..."); + return edit; + } + return pack.description; + } case Qt::DecorationRole: { + if (m_logoMap.contains(pack.logoName)) { + return (m_logoMap.value(pack.logoName)); + } + QIcon icon = APPLICATION->getThemedIcon("screenshot-placeholder"); + ((ListModel*)this)->requestLogo(pack.logoName, pack.logoUrl); + return icon; + } case Qt::UserRole: { + QVariant v; + v.setValue(pack); + return v; } - return pack.description; - } else if (role == Qt::DecorationRole) { - if (m_logoMap.contains(pack.logoName)) { - return (m_logoMap.value(pack.logoName)); - } - QIcon icon = APPLICATION->getThemedIcon("screenshot-placeholder"); - ((ListModel*)this)->requestLogo(pack.logoName, pack.logoUrl); - return icon; - } else if (role == Qt::UserRole) { - QVariant v; - v.setValue(pack); - return v; + case Qt::SizeHintRole: + return QSize(0, 58); + case UserDataTypes::TITLE: + return pack.name; + case UserDataTypes::DESCRIPTION: + return pack.description; + case UserDataTypes::SELECTED: + return false; + default: + break; } - return QVariant(); } diff --git a/launcher/ui/pages/modplatform/flame/FlamePage.cpp b/launcher/ui/pages/modplatform/flame/FlamePage.cpp index 7d2ba2e2f..a65b65858 100644 --- a/launcher/ui/pages/modplatform/flame/FlamePage.cpp +++ b/launcher/ui/pages/modplatform/flame/FlamePage.cpp @@ -43,6 +43,10 @@ #include "InstanceImportTask.h" #include "Json.h" #include "ui/dialogs/NewInstanceDialog.h" +#include "ui/widgets/ProjectItem.h" +#include "modplatform/flame/FlameAPI.h" + +static FlameAPI api; FlamePage::FlamePage(NewInstanceDialog* dialog, QWidget* parent) : QWidget(parent), ui(new Ui::FlamePage), dialog(dialog) { @@ -66,6 +70,9 @@ FlamePage::FlamePage(NewInstanceDialog* dialog, QWidget* parent) : QWidget(paren connect(ui->sortByBox, SIGNAL(currentIndexChanged(int)), this, SLOT(triggerSearch())); connect(ui->packView->selectionModel(), &QItemSelectionModel::currentChanged, this, &FlamePage::onSelectionChanged); connect(ui->versionSelectionBox, &QComboBox::currentTextChanged, this, &FlamePage::onVersionSelectionChanged); + + ui->packView->setItemDelegate(new ProjectItemDelegate(this)); + ui->packDescription->setMetaEntry("FlamePacks"); } FlamePage::~FlamePage() @@ -250,7 +257,10 @@ void FlamePage::updateUi() text += "- " + tr("Source code: %1").arg(current.extra.sourceUrl) + "
"; } + text += "
"; + text += api.getModDescription(current.addonId).toUtf8(); ui->packDescription->setHtml(text + current.description); + ui->packDescription->flush(); } diff --git a/launcher/ui/pages/modplatform/flame/FlamePage.ui b/launcher/ui/pages/modplatform/flame/FlamePage.ui index 1a3d02255..71d195135 100644 --- a/launcher/ui/pages/modplatform/flame/FlamePage.ui +++ b/launcher/ui/pages/modplatform/flame/FlamePage.ui @@ -66,7 +66,7 @@
- + true @@ -99,6 +99,13 @@ + + + ProjectDescriptionPage + QTextBrowser +
ui/widgets/ProjectDescriptionPage.h
+
+
packView packDescription diff --git a/launcher/ui/themes/DarkTheme.cpp b/launcher/ui/themes/DarkTheme.cpp index 07a2efd2d..48231b53e 100644 --- a/launcher/ui/themes/DarkTheme.cpp +++ b/launcher/ui/themes/DarkTheme.cpp @@ -31,7 +31,7 @@ QPalette DarkTheme::colorScheme() darkPalette.setColor(QPalette::ButtonText, Qt::white); darkPalette.setColor(QPalette::BrightText, Qt::red); darkPalette.setColor(QPalette::Link, QColor(47,163,198)); - darkPalette.setColor(QPalette::Highlight, QColor(145,205,92)); + darkPalette.setColor(QPalette::Highlight, QColor(150,219,89)); darkPalette.setColor(QPalette::HighlightedText, Qt::black); darkPalette.setColor(QPalette::PlaceholderText, Qt::darkGray); return fadeInactive(darkPalette, fadeAmount(), fadeColor()); diff --git a/launcher/ui/widgets/JavaSettingsWidget.cpp b/launcher/ui/widgets/JavaSettingsWidget.cpp index 314a126e4..c7c4dbbd9 100644 --- a/launcher/ui/widgets/JavaSettingsWidget.cpp +++ b/launcher/ui/widgets/JavaSettingsWidget.cpp @@ -245,7 +245,7 @@ void JavaSettingsWidget::memoryValueChanged(int) } } -void JavaSettingsWidget::javaVersionSelected(BaseVersionPtr version) +void JavaSettingsWidget::javaVersionSelected(BaseVersion::Ptr version) { auto java = std::dynamic_pointer_cast(version); if(!java) diff --git a/launcher/ui/widgets/JavaSettingsWidget.h b/launcher/ui/widgets/JavaSettingsWidget.h index 0d280daf3..5344e2cd1 100644 --- a/launcher/ui/widgets/JavaSettingsWidget.h +++ b/launcher/ui/widgets/JavaSettingsWidget.h @@ -60,7 +60,7 @@ public: protected slots: void memoryValueChanged(int); void javaPathEdited(const QString &path); - void javaVersionSelected(BaseVersionPtr version); + void javaVersionSelected(BaseVersion::Ptr version); void on_javaBrowseBtn_clicked(); void on_javaStatusBtn_clicked(); void checkFinished(JavaCheckResult result); diff --git a/launcher/ui/widgets/ModFilterWidget.h b/launcher/ui/widgets/ModFilterWidget.h index 958a1e2b0..706ffd21a 100644 --- a/launcher/ui/widgets/ModFilterWidget.h +++ b/launcher/ui/widgets/ModFilterWidget.h @@ -49,7 +49,7 @@ public: auto getFilter() -> std::shared_ptr; auto changed() const -> bool { return m_last_version_id != m_version_id; } - Meta::VersionListPtr versionList() { return m_version_list; } + Meta::VersionList::Ptr versionList() { return m_version_list; } private: ModFilterWidget(Version def, QWidget* parent = nullptr); @@ -73,7 +73,7 @@ private: /* Version stuff */ QButtonGroup m_mcVersion_buttons; - Meta::VersionListPtr m_version_list; + Meta::VersionList::Ptr m_version_list; /* Used to tell if the filter was changed since the last getFilter() call */ VersionButtonID m_last_version_id = VersionButtonID::Strict; diff --git a/launcher/ui/widgets/VersionSelectWidget.cpp b/launcher/ui/widgets/VersionSelectWidget.cpp index cc4fc6a2f..404860d90 100644 --- a/launcher/ui/widgets/VersionSelectWidget.cpp +++ b/launcher/ui/widgets/VersionSelectWidget.cpp @@ -142,7 +142,7 @@ void VersionSelectWidget::changeProgress(qint64 current, qint64 total) void VersionSelectWidget::currentRowChanged(const QModelIndex& current, const QModelIndex&) { auto variant = m_proxyModel->data(current, BaseVersionList::VersionPointerRole); - emit selectedVersionChanged(variant.value()); + emit selectedVersionChanged(variant.value()); } void VersionSelectWidget::preselect() @@ -186,11 +186,11 @@ bool VersionSelectWidget::hasVersions() const return m_proxyModel->rowCount(QModelIndex()) != 0; } -BaseVersionPtr VersionSelectWidget::selectedVersion() const +BaseVersion::Ptr VersionSelectWidget::selectedVersion() const { auto currentIndex = listView->selectionModel()->currentIndex(); auto variant = m_proxyModel->data(currentIndex, BaseVersionList::VersionPointerRole); - return variant.value(); + return variant.value(); } void VersionSelectWidget::setExactFilter(BaseVersionList::ModelRoles role, QString filter) diff --git a/launcher/ui/widgets/VersionSelectWidget.h b/launcher/ui/widgets/VersionSelectWidget.h index f56daa8aa..e75efc6f6 100644 --- a/launcher/ui/widgets/VersionSelectWidget.h +++ b/launcher/ui/widgets/VersionSelectWidget.h @@ -40,7 +40,7 @@ public: void loadList(); bool hasVersions() const; - BaseVersionPtr selectedVersion() const; + BaseVersion::Ptr selectedVersion() const; void selectRecommended(); void selectCurrent(); @@ -54,7 +54,7 @@ public: void setResizeOn(int column); signals: - void selectedVersionChanged(BaseVersionPtr version); + void selectedVersionChanged(BaseVersion::Ptr version); protected: virtual void closeEvent ( QCloseEvent* ); diff --git a/libraries/LocalPeer/src/LocalPeer.cpp b/libraries/LocalPeer/src/LocalPeer.cpp index 3c3d8b4ce..b7149c408 100644 --- a/libraries/LocalPeer/src/LocalPeer.cpp +++ b/libraries/LocalPeer/src/LocalPeer.cpp @@ -210,7 +210,7 @@ void LocalPeer::receiveConnection() return; } - while (socket->bytesAvailable() < (int)sizeof(quint32)) + while (socket->bytesAvailable() < static_cast(sizeof(quint32))) { socket->waitForReadyRead(); } diff --git a/libraries/katabasis/src/DeviceFlow.cpp b/libraries/katabasis/src/DeviceFlow.cpp index ba1d121d0..f78fd6200 100644 --- a/libraries/katabasis/src/DeviceFlow.cpp +++ b/libraries/katabasis/src/DeviceFlow.cpp @@ -445,7 +445,7 @@ void DeviceFlow::onRefreshError(QNetworkReply::NetworkError error, QNetworkReply if(refreshReply) { refreshReply->deleteLater(); } - qDebug() << "DeviceFlow::onRefreshFinished: Error" << (int)error << " - " << errorString; + qDebug() << "DeviceFlow::onRefreshFinished: Error" << static_cast(error) << " - " << errorString; } } diff --git a/libraries/murmur2/src/MurmurHash2.cpp b/libraries/murmur2/src/MurmurHash2.cpp index b625efb1c..c13608f07 100644 --- a/libraries/murmur2/src/MurmurHash2.cpp +++ b/libraries/murmur2/src/MurmurHash2.cpp @@ -55,12 +55,12 @@ uint32_t MurmurHash2(std::ifstream&& file_stream, std::size_t buffer_size, std:: // Mix 4 bytes at a time into the hash if (index == 0) - FourBytes_MurmurHash2((unsigned char*)&data, info); + FourBytes_MurmurHash2(reinterpret_cast(&data), info); } } while (!file_stream.eof()); // Do one last bit shuffle in the hash - FourBytes_MurmurHash2((unsigned char*)&data, info); + FourBytes_MurmurHash2(reinterpret_cast(&data), info); delete[] buffer; @@ -72,7 +72,7 @@ void FourBytes_MurmurHash2(const unsigned char* data, IncrementalHashInfo& prev) { if (prev.len >= 4) { // Not the final mix - uint32_t k = *(uint32_t*)data; + uint32_t k = *reinterpret_cast(data); k *= m; k ^= k >> r; diff --git a/program_info/CMakeLists.txt b/program_info/CMakeLists.txt index 3c8cad0f9..8c6827119 100644 --- a/program_info/CMakeLists.txt +++ b/program_info/CMakeLists.txt @@ -15,12 +15,14 @@ set(Launcher_Name "${Launcher_CommonName}" PARENT_SCOPE) set(Launcher_DisplayName "${Launcher_DisplayName}" PARENT_SCOPE) set(Launcher_Copyright "Prism Launcher Contributors\\n© 2021-2022 PolyMC Contributors \\n© 2012-2021 MultiMC Contributors") +set(Launcher_Copyright_Mac "Prism Launcher Contributors, © 2021-2022 PolyMC Contributors and © 2012-2021 MultiMC Contributors" PARENT_SCOPE) set(Launcher_Copyright "${Launcher_Copyright}" PARENT_SCOPE) set(Launcher_Domain "prismlauncher.org" PARENT_SCOPE) set(Launcher_UserAgent "${Launcher_CommonName}/${Launcher_VERSION_NAME}" PARENT_SCOPE) set(Launcher_ConfigFile "prismlauncher.cfg" PARENT_SCOPE) set(Launcher_Git "https://github.com/PrismLauncher/PrismLauncher" PARENT_SCOPE) set(Launcher_DesktopFileName "org.prismlauncher.PrismLauncher.desktop" PARENT_SCOPE) +set(Launcher_SVGFileName "org.prismlauncher.PrismLauncher.svg" PARENT_SCOPE) set(Launcher_Desktop "program_info/org.prismlauncher.PrismLauncher.desktop" PARENT_SCOPE) set(Launcher_mrpack_MIMEInfo "program_info/modrinth-mrpack-mime.xml" PARENT_SCOPE) diff --git a/program_info/genicons.sh b/program_info/genicons.sh index bfe756d82..42592c4ee 100755 --- a/program_info/genicons.sh +++ b/program_info/genicons.sh @@ -1,39 +1,73 @@ -#/bin/bash +#!/bin/bash -# ICO +svg2png() { + input_file="$1" + output_file="$2" + width="$3" + height="$4" -inkscape -w 16 -h 16 -o prismlauncher_16.png org.prismlauncher.PrismLauncher.svg -inkscape -w 24 -h 24 -o prismlauncher_24.png org.prismlauncher.PrismLauncher.svg -inkscape -w 32 -h 32 -o prismlauncher_32.png org.prismlauncher.PrismLauncher.svg -inkscape -w 48 -h 48 -o prismlauncher_48.png org.prismlauncher.PrismLauncher.svg -inkscape -w 64 -h 64 -o prismlauncher_64.png org.prismlauncher.PrismLauncher.svg -inkscape -w 128 -h 128 -o prismlauncher_128.png org.prismlauncher.PrismLauncher.svg + inkscape -w "$width" -h "$height" -o "$output_file" "$input_file" +} -convert prismlauncher_128.png prismlauncher_64.png prismlauncher_48.png prismlauncher_32.png prismlauncher_24.png prismlauncher_16.png prismlauncher.ico +sipsresize() { + input_file="$1" + output_file="$2" + width="$3" + height="$4" -rm -f prismlauncher_*.png + sips -z "$width" "$height" "$input_file" --out "$output_file" +} -inkscape -w 1024 -h 1024 -o prismlauncher_1024.png org.prismlauncher.PrismLauncher.bigsur.svg +if command -v "inkscape" && command -v "icotool"; then + # Windows ICO + d=$(mktemp -d) -mkdir prismlauncher.iconset + svg2png org.prismlauncher.PrismLauncher.svg "$d/prismlauncher_16.png" 16 16 + svg2png org.prismlauncher.PrismLauncher.svg "$d/prismlauncher_24.png" 24 24 + svg2png org.prismlauncher.PrismLauncher.svg "$d/prismlauncher_32.png" 32 32 + svg2png org.prismlauncher.PrismLauncher.svg "$d/prismlauncher_48.png" 48 48 + svg2png org.prismlauncher.PrismLauncher.svg "$d/prismlauncher_64.png" 64 64 + svg2png org.prismlauncher.PrismLauncher.svg "$d/prismlauncher_128.png" 128 128 + svg2png org.prismlauncher.PrismLauncher.svg "$d/prismlauncher_256.png" 256 256 -sips -z 16 16 prismlauncher_1024.png --out prismlauncher.iconset/icon_16x16.png -sips -z 32 32 prismlauncher_1024.png --out prismlauncher.iconset/icon_16x16@2x.png -sips -z 32 32 prismlauncher_1024.png --out prismlauncher.iconset/icon_32x32.png -sips -z 64 64 prismlauncher_1024.png --out prismlauncher.iconset/icon_32x32@2x.png -sips -z 128 128 prismlauncher_1024.png --out prismlauncher.iconset/icon_128x128.png -sips -z 256 256 prismlauncher_1024.png --out prismlauncher.iconset/icon_128x128@2x.png -sips -z 256 256 prismlauncher_1024.png --out prismlauncher.iconset/icon_256x256.png -sips -z 512 512 prismlauncher_1024.png --out prismlauncher.iconset/icon_256x256@2x.png -sips -z 512 512 prismlauncher_1024.png --out prismlauncher.iconset/icon_512x512.png -cp prismlauncher_1024.png prismlauncher.iconset/icon_512x512@2x.png + rm prismlauncher.ico && icotool -o prismlauncher.ico -c \ + "$d/prismlauncher_256.png" \ + "$d/prismlauncher_128.png" \ + "$d/prismlauncher_64.png" \ + "$d/prismlauncher_48.png" \ + "$d/prismlauncher_32.png" \ + "$d/prismlauncher_24.png" \ + "$d/prismlauncher_16.png" +else + echo "ERROR: Windows icons were NOT generated!" >&2 + echo "ERROR: requires inkscape and icotool in PATH" +fi -iconutil -c icns prismlauncher.iconset +if command -v "inkscape" && command -v "sips" && command -v "iconutil"; then + # macOS ICNS + d=$(mktemp -d) -rm -f prismlauncher_*.png -rm -rf prismlauncher.iconset + d="$d/prismlauncher.iconset" + mkdir -p "$d" + + svg2png org.prismlauncher.PrismLauncher.bigsur.svg "$d/icon_512x512@2x.png" 1024 1024 + sipsresize "$d/icon_512x512@2.png" "$d/icon_16x16.png" 16 16 + sipsresize "$d/icon_512x512@2.png" "$d/icon_16x16@2.png" 32 32 + sipsresize "$d/icon_512x512@2.png" "$d/icon_32x32.png" 32 32 + sipsresize "$d/icon_512x512@2.png" "$d/icon_32x32@2.png" 64 64 + sipsresize "$d/icon_512x512@2.png" "$d/icon_128x128.png" 128 128 + sipsresize "$d/icon_512x512@2.png" "$d/icon_128x128@2.png" 256 256 + sipsresize "$d/icon_512x512@2.png" "$d/icon_256x256.png" 256 256 + sipsresize "$d/icon_512x512@2.png" "$d/icon_256x256@2.png" 512 512 + iconutil -c icns "$d" +else + echo "ERROR: macOS icons were NOT generated!" >&2 + echo "ERROR: requires inkscape, sips and iconutil in PATH" +fi + +# replace icon in themes for dir in ../launcher/resources/*/scalable do - cp -v org.prismlauncher.PrismLauncher.svg $dir/launcher.svg + cp -v org.prismlauncher.PrismLauncher.svg "$dir/launcher.svg" done diff --git a/program_info/prismlauncher.6.scd b/program_info/prismlauncher.6.scd index e3c7de860..f979e4571 100644 --- a/program_info/prismlauncher.6.scd +++ b/program_info/prismlauncher.6.scd @@ -26,6 +26,9 @@ Here are the current features of Prism Launcher. *-l, --launch*=INSTANCE_ID Launch the instance specified by INSTANCE_ID. +*--show*=INSTANCE_ID + Show the configuration window of the instance specified by INSTANCE_ID. + *--alive* Write a small 'live.check' file after Prism Launcher starts. diff --git a/program_info/prismlauncher.ico b/program_info/prismlauncher.ico index e4529f938..2f0fa67ff 100644 Binary files a/program_info/prismlauncher.ico and b/program_info/prismlauncher.ico differ diff --git a/program_info/prismlauncher.manifest.in b/program_info/prismlauncher.manifest.in index 1d7644450..6f4467c7d 100644 --- a/program_info/prismlauncher.manifest.in +++ b/program_info/prismlauncher.manifest.in @@ -10,7 +10,7 @@ - + Custom Minecraft launcher for managing multiple installs. diff --git a/program_info/win_install.nsi.in b/program_info/win_install.nsi.in index 1c1f29dae..0cd7ea118 100644 --- a/program_info/win_install.nsi.in +++ b/program_info/win_install.nsi.in @@ -4,7 +4,7 @@ Unicode true -Name "@Launcher_CommonName@" +Name "@Launcher_DisplayName@" InstallDir "$LOCALAPPDATA\Programs\@Launcher_CommonName@" InstallDirRegKey HKCU "Software\@Launcher_CommonName@" "InstallDir" RequestExecutionLevel user @@ -113,7 +113,7 @@ VIAddVersionKey /LANG=${LANG_ENGLISH} "ProductVersion" "@Launcher_VERSION_NAME4@ ;-------------------------------- ; The stuff to install -Section "@Launcher_CommonName@" +Section "@Launcher_DisplayName@" SectionIn RO diff --git a/tests/FileSystem_test.cpp b/tests/FileSystem_test.cpp index 47a963b0c..21270f6f6 100644 --- a/tests/FileSystem_test.cpp +++ b/tests/FileSystem_test.cpp @@ -183,6 +183,32 @@ slots: f(); } + void test_copy_single_file() + { + QTemporaryDir tempDir; + tempDir.setAutoRemove(true); + + { + QString file = QFINDTESTDATA("testdata/FileSystem/test_folder/pack.mcmeta"); + + qDebug() << "From:" << file << "To:" << tempDir.path(); + + QDir target_dir(FS::PathCombine(tempDir.path(), "pack.mcmeta")); + qDebug() << tempDir.path(); + qDebug() << target_dir.path(); + FS::copy c(file, target_dir.filePath("pack.mcmeta")); + c(); + + auto filter = QDir::Filter::Files; + + for (auto entry: target_dir.entryList(filter)) { + qDebug() << entry; + } + + QVERIFY(target_dir.entryList(filter).contains("pack.mcmeta")); + } + } + void test_getDesktop() { QCOMPARE(FS::getDesktopDir(), QStandardPaths::writableLocation(QStandardPaths::DesktopLocation));