Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
This commit is contained in:
Trial97
2023-11-17 22:26:17 +02:00
119 changed files with 7407 additions and 904 deletions

View File

@ -58,6 +58,7 @@
#include "ui/pages/global/APIPage.h"
#include "ui/pages/global/AccountListPage.h"
#include "ui/pages/global/CustomCommandsPage.h"
#include "ui/pages/global/EnvironmentVariablesPage.h"
#include "ui/pages/global/ExternalToolsPage.h"
#include "ui/pages/global/JavaPage.h"
#include "ui/pages/global/LanguagePage.h"
@ -643,6 +644,7 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
// Minecraft mods
m_settings->registerSetting("ModMetadataDisabled", false);
m_settings->registerSetting("ModDependenciesDisabled", false);
// Minecraft offline player name
m_settings->registerSetting("LastOfflinePlayerName", "");
@ -719,6 +721,8 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
m_settings->registerSetting("CloseAfterLaunch", false);
m_settings->registerSetting("QuitAfterGameStop", false);
m_settings->registerSetting("Env", QVariant(QMap<QString, QVariant>()));
// Custom Microsoft Authentication Client ID
m_settings->registerSetting("MSAClientIDOverride", "");
@ -744,6 +748,7 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
m_globalSettingsProvider->addPage<JavaPage>();
m_globalSettingsProvider->addPage<LanguagePage>();
m_globalSettingsProvider->addPage<CustomCommandsPage>();
m_globalSettingsProvider->addPage<EnvironmentVariablesPage>();
m_globalSettingsProvider->addPage<ProxyPage>();
m_globalSettingsProvider->addPage<ExternalToolsPage>();
m_globalSettingsProvider->addPage<AccountListPage>();

View File

@ -388,7 +388,7 @@ QString BaseInstance::name() const
QString BaseInstance::windowTitle() const
{
return BuildConfig.LAUNCHER_DISPLAYNAME + ": " + name().replace(QRegularExpression("\\s+"), " ");
return BuildConfig.LAUNCHER_DISPLAYNAME + ": " + name();
}
// FIXME: why is this here? move it to MinecraftInstance!!!

View File

@ -64,7 +64,7 @@ class LaunchTask;
class BaseInstance;
// pointer for lazy people
typedef std::shared_ptr<BaseInstance> InstancePtr;
using InstancePtr = std::shared_ptr<BaseInstance>;
/*!
* \brief Base class for instances.

View File

@ -51,7 +51,7 @@ class BaseVersionList : public QAbstractListModel {
ArchitectureRole,
SortRole
};
typedef QList<int> RoleList;
using RoleList = QList<int>;
explicit BaseVersionList(QObject* parent = 0);

View File

@ -139,6 +139,7 @@ set(NET_SOURCES
net/HeaderProxy.h
net/RawHeaderProxy.h
net/ApiHeaderProxy.h
net/StaticHeaderProxy.h
net/ApiDownload.h
net/ApiDownload.cpp
net/ApiUpload.cpp
@ -888,6 +889,8 @@ SET(LAUNCHER_SOURCES
ui/pages/global/AccountListPage.h
ui/pages/global/CustomCommandsPage.cpp
ui/pages/global/CustomCommandsPage.h
ui/pages/global/EnvironmentVariablesPage.cpp
ui/pages/global/EnvironmentVariablesPage.h
ui/pages/global/ExternalToolsPage.cpp
ui/pages/global/ExternalToolsPage.h
ui/pages/global/JavaPage.cpp
@ -1041,6 +1044,8 @@ SET(LAUNCHER_SOURCES
ui/widgets/Common.h
ui/widgets/CustomCommands.cpp
ui/widgets/CustomCommands.h
ui/widgets/EnvironmentVariables.cpp
ui/widgets/EnvironmentVariables.h
ui/widgets/DropLabel.cpp
ui/widgets/DropLabel.h
ui/widgets/FocusLineEdit.cpp
@ -1151,6 +1156,7 @@ qt_wrap_ui(LAUNCHER_UI
ui/pages/modplatform/technic/TechnicPage.ui
ui/widgets/InstanceCardWidget.ui
ui/widgets/CustomCommands.ui
ui/widgets/EnvironmentVariables.ui
ui/widgets/InfoFrame.ui
ui/widgets/ModFilterWidget.ui
ui/widgets/SubTaskProgressBar.ui
@ -1308,7 +1314,7 @@ install(TARGETS ${Launcher_Name}
FRAMEWORK DESTINATION ${FRAMEWORK_DEST_DIR} COMPONENT Runtime
)
if(NOT APPLE OR (DEFINED Launcher_BUILD_UPDATER AND Launcher_BUILD_UPDATER))
if(Launcher_BUILD_UPDATER)
# Updater
add_library(prism_updater_logic STATIC ${PRISMUPDATER_SOURCES} ${TASKS_SOURCES} ${PRISMUPDATER_UI})
target_include_directories(prism_updater_logic PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})

View File

@ -123,26 +123,35 @@ namespace fs = ghc::filesystem;
#if defined(__MINGW32__)
typedef struct _DUPLICATE_EXTENTS_DATA {
struct _DUPLICATE_EXTENTS_DATA {
HANDLE FileHandle;
LARGE_INTEGER SourceFileOffset;
LARGE_INTEGER TargetFileOffset;
LARGE_INTEGER ByteCount;
} DUPLICATE_EXTENTS_DATA, *PDUPLICATE_EXTENTS_DATA;
};
typedef struct _FSCTL_GET_INTEGRITY_INFORMATION_BUFFER {
using DUPLICATE_EXTENTS_DATA = _DUPLICATE_EXTENTS_DATA;
using PDUPLICATE_EXTENTS_DATA = _DUPLICATE_EXTENTS_DATA*;
struct _FSCTL_GET_INTEGRITY_INFORMATION_BUFFER {
WORD ChecksumAlgorithm; // Checksum algorithm. e.g. CHECKSUM_TYPE_UNCHANGED, CHECKSUM_TYPE_NONE, CHECKSUM_TYPE_CRC32
WORD Reserved; // Must be 0
DWORD Flags; // FSCTL_INTEGRITY_FLAG_xxx
DWORD ChecksumChunkSizeInBytes;
DWORD ClusterSizeInBytes;
} FSCTL_GET_INTEGRITY_INFORMATION_BUFFER, *PFSCTL_GET_INTEGRITY_INFORMATION_BUFFER;
};
typedef struct _FSCTL_SET_INTEGRITY_INFORMATION_BUFFER {
using FSCTL_GET_INTEGRITY_INFORMATION_BUFFER = _FSCTL_GET_INTEGRITY_INFORMATION_BUFFER;
using PFSCTL_GET_INTEGRITY_INFORMATION_BUFFER = _FSCTL_GET_INTEGRITY_INFORMATION_BUFFER*;
struct _FSCTL_SET_INTEGRITY_INFORMATION_BUFFER {
WORD ChecksumAlgorithm; // Checksum algorithm. e.g. CHECKSUM_TYPE_UNCHANGED, CHECKSUM_TYPE_NONE, CHECKSUM_TYPE_CRC32
WORD Reserved; // Must be 0
DWORD Flags; // FSCTL_INTEGRITY_FLAG_xxx
} FSCTL_SET_INTEGRITY_INFORMATION_BUFFER, *PFSCTL_SET_INTEGRITY_INFORMATION_BUFFER;
};
using FSCTL_SET_INTEGRITY_INFORMATION_BUFFER = _FSCTL_SET_INTEGRITY_INFORMATION_BUFFER;
using PFSCTL_SET_INTEGRITY_INFORMATION_BUFFER = _FSCTL_SET_INTEGRITY_INFORMATION_BUFFER*;
#endif
@ -934,6 +943,8 @@ bool createShortcut(QString destination, QString target, QStringList args, QStri
<< "\n";
stream << "Type=Application"
<< "\n";
stream << "Categories=Game;ActionGame;AdventureGame;Simulation"
<< "\n";
stream << "Exec=\"" << target.toLocal8Bit() << "\"" << argstring.toLocal8Bit() << "\n";
stream << "Name=" << name.toLocal8Bit() << "\n";
if (!icon.isEmpty()) {

View File

@ -290,7 +290,7 @@ void InstanceList::deleteGroup(const GroupId& name)
qDebug() << "Remove" << instID << "from group" << name;
removed = true;
auto idx = getInstIndex(instance.get());
if (idx > 0)
if (idx >= 0)
emit dataChanged(index(idx), index(idx), { GroupRole });
}
}
@ -315,7 +315,7 @@ void InstanceList::renameGroup(const QString& src, const QString& dst)
qDebug() << "Set" << instID << "group to" << dst;
modified = true;
auto idx = getInstIndex(instance.get());
if (idx > 0)
if (idx >= 0)
emit dataChanged(index(idx), index(idx), { GroupRole });
}
}
@ -947,9 +947,12 @@ QString InstanceList::getStagedInstancePath()
bool InstanceList::commitStagedInstance(const QString& path,
InstanceName const& instanceName,
const QString& groupName,
QString groupName,
InstanceTask const& commiting)
{
if (groupName.isEmpty() && !groupName.isNull())
groupName = QString();
QDir dir;
QString instID;
InstancePtr inst;

View File

@ -130,7 +130,7 @@ class InstanceList : public QAbstractListModel {
* should_override is used when another similar instance already exists, and we want to override it
* - for instance, when updating it.
*/
bool commitStagedInstance(const QString& keyPath, const InstanceName& instanceName, const QString& groupName, const InstanceTask&);
bool commitStagedInstance(const QString& keyPath, const InstanceName& instanceName, QString groupName, const InstanceTask&);
/**
* Destroy a previously created staging area given by @keyPath - used when creation fails.

View File

@ -89,7 +89,7 @@ void LaunchController::decideAccount()
// Tell the user they need to log in at least one account in order to play.
auto reply = CustomMessageBox::selectable(m_parentWidget, tr("No Accounts"),
tr("In order to play Minecraft, you must have at least one Microsoft "
"account which owns Minecraft logged in."
"account which owns Minecraft logged in. "
"Would you like to open the account manager to add an account now?"),
QMessageBox::Information, QMessageBox::Yes | QMessageBox::No)
->exec();
@ -106,7 +106,7 @@ void LaunchController::decideAccount()
// Select the account to use. If the instance has a specific account set, that will be used. Otherwise, the default account will be used
auto instanceAccountId = m_instance->settings()->get("InstanceAccountId").toString();
auto instanceAccountIndex = accounts->findAccountByProfileId(instanceAccountId);
if (instanceAccountIndex == -1) {
if (instanceAccountIndex == -1 || instanceAccountId.isEmpty()) {
m_accountToUse = accounts->defaultAccount();
} else {
m_accountToUse = accounts->at(instanceAccountIndex);

View File

@ -172,7 +172,7 @@ class ExportToZipTask : public Task {
void setExcludeFiles(QStringList excludeFiles) { m_exclude_files = excludeFiles; }
void addExtraFile(QString fileName, QByteArray data) { m_extra_files.insert(fileName, data); }
typedef std::optional<QString> ZipResult;
using ZipResult = std::optional<QString>;
protected:
virtual void executeTask() override;

View File

@ -5,6 +5,7 @@
#include <QPixmapCache>
#include <QThread>
#include <QTime>
#include <limits>
#define GET_TYPE() \
Qt::ConnectionType type; \
@ -100,10 +101,14 @@ class PixmapCache final : public QObject {
*/
bool _markCacheMissByEviciton()
{
static constexpr uint maxInt = static_cast<uint>(std::numeric_limits<int>::max());
static constexpr uint step = 10240;
static constexpr int oneSecond = 1000;
auto now = QTime::currentTime();
if (!m_last_cache_miss_by_eviciton.isNull()) {
auto diff = m_last_cache_miss_by_eviciton.msecsTo(now);
if (diff < 1000) { // less than a second ago
if (diff < oneSecond) { // less than a second ago
++m_consecutive_fast_evicitons;
} else {
m_consecutive_fast_evicitons = 0;
@ -111,11 +116,17 @@ class PixmapCache final : public QObject {
}
m_last_cache_miss_by_eviciton = now;
if (m_consecutive_fast_evicitons >= m_consecutive_fast_evicitons_threshold) {
// double the cache size
auto newSize = _cacheLimit() * 2;
qDebug() << m_consecutive_fast_evicitons << "pixmap cache misses by eviction happened too fast, doubling cache size to"
<< newSize;
_setCacheLimit(newSize);
// increase the cache size
uint newSize = _cacheLimit() + step;
if (newSize >= maxInt) { // increase it until you overflow :D
newSize = maxInt;
qDebug() << m_consecutive_fast_evicitons
<< tr("pixmap cache misses by eviction happened too fast, doing nothing as the cache size reached it's limit");
} else {
qDebug() << m_consecutive_fast_evicitons
<< tr("pixmap cache misses by eviction happened too fast, increasing cache size to") << static_cast<int>(newSize);
}
_setCacheLimit(static_cast<int>(newSize));
m_consecutive_fast_evicitons = 0;
return true;
}

View File

@ -10,7 +10,7 @@ class VersionProxyModel : public QAbstractProxyModel {
Q_OBJECT
public:
enum Column { Name, ParentVersion, Branch, Type, Architecture, Path, Time };
typedef QHash<BaseVersionList::ModelRoles, std::shared_ptr<Filter>> FilterMap;
using FilterMap = QHash<BaseVersionList::ModelRoles, std::shared_ptr<Filter>>;
public:
VersionProxyModel(QObject* parent = 0);

View File

@ -22,8 +22,8 @@ struct JavaCheckResult {
enum class Validity { Errored, ReturnedInvalidData, Valid } validity = Validity::Errored;
};
typedef shared_qobject_ptr<QProcess> QProcessPtr;
typedef shared_qobject_ptr<JavaChecker> JavaCheckerPtr;
using QProcessPtr = shared_qobject_ptr<QProcess>;
using JavaCheckerPtr = shared_qobject_ptr<JavaChecker>;
class JavaChecker : public QObject {
Q_OBJECT
public:

View File

@ -20,7 +20,7 @@
#include "tasks/Task.h"
class JavaCheckerJob;
typedef shared_qobject_ptr<JavaCheckerJob> JavaCheckerJobPtr;
using JavaCheckerJobPtr = shared_qobject_ptr<JavaCheckerJob>;
// FIXME: this just seems horribly redundant
class JavaCheckerJob : public Task {

View File

@ -42,4 +42,4 @@ struct JavaInstall : public BaseVersion {
bool recommended = false;
};
typedef std::shared_ptr<JavaInstall> JavaInstallPtr;
using JavaInstallPtr = std::shared_ptr<JavaInstall>;

View File

@ -34,6 +34,7 @@
*/
#include <QDir>
#include <QFileInfo>
#include <QString>
#include <QStringList>
@ -335,6 +336,7 @@ QList<QString> JavaUtils::FindJavaPaths()
}
}
candidates.append(getMinecraftJavaBundle());
candidates = addJavasFromEnv(candidates);
candidates.removeDuplicates();
return candidates;
@ -360,6 +362,7 @@ QList<QString> JavaUtils::FindJavaPaths()
javas.append(systemLibraryJVMDir.absolutePath() + "/" + java + "/Contents/Home/bin/java");
javas.append(systemLibraryJVMDir.absolutePath() + "/" + java + "/Contents/Commands/java");
}
javas.append(getMinecraftJavaBundle());
javas = addJavasFromEnv(javas);
javas.removeDuplicates();
return javas;
@ -411,6 +414,7 @@ QList<QString> JavaUtils::FindJavaPaths()
// javas downloaded by sdkman
scanJavaDirs(FS::PathCombine(home, ".sdkman/candidates/java"));
javas.append(getMinecraftJavaBundle());
javas = addJavasFromEnv(javas);
javas.removeDuplicates();
return javas;
@ -423,6 +427,7 @@ QList<QString> JavaUtils::FindJavaPaths()
QList<QString> javas;
javas.append(this->GetDefaultJava()->path);
javas.append(getMinecraftJavaBundle());
return addJavasFromEnv(javas);
}
#endif
@ -431,3 +436,50 @@ QString JavaUtils::getJavaCheckPath()
{
return APPLICATION->getJarPath("JavaCheck.jar");
}
QStringList getMinecraftJavaBundle()
{
QString partialPath;
QString executable = "java";
QStringList processpaths;
#if defined(Q_OS_OSX)
partialPath = FS::PathCombine(QDir::homePath(), "Library/Application Support");
#elif defined(Q_OS_WIN32)
partialPath = QProcessEnvironment::systemEnvironment().value("LOCALAPPDATA", "");
executable += "w.exe";
// add the microsoft store version of the launcher to the search. the current path is:
// C:\Users\USERNAME\AppData\Local\Packages\Microsoft.4297127D64EC6_8wekyb3d8bbwe\LocalCache\Local\runtime
auto minecraftMSStorePath =
FS::PathCombine(QFileInfo(partialPath).absolutePath(), "Local", "Packages", "Microsoft.4297127D64EC6_8wekyb3d8bbwe");
minecraftMSStorePath = FS::PathCombine(minecraftMSStorePath, "LocalCache", "Local", "runtime");
processpaths << minecraftMSStorePath;
#else
partialPath = QDir::homePath();
#endif
auto minecraftDataPath = FS::PathCombine(partialPath, ".minecraft", "runtime");
processpaths << minecraftDataPath;
QStringList javas;
while (!processpaths.isEmpty()) {
auto dirPath = processpaths.takeFirst();
QDir dir(dirPath);
if (!dir.exists())
continue;
auto entries = dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);
auto binFound = false;
for (auto& entry : entries) {
if (entry.baseName() == "bin") {
javas.append(FS::PathCombine(entry.canonicalFilePath(), executable));
binFound = true;
break;
}
}
if (!binFound) {
for (auto& entry : entries) {
processpaths << entry.canonicalFilePath();
}
}
}
return javas;
}

View File

@ -26,6 +26,7 @@
QString stripVariableEntries(QString name, QString target, QString remove);
QProcessEnvironment CleanEnviroment();
QStringList getMinecraftJavaBundle();
class JavaUtils : public QObject {
Q_OBJECT

View File

@ -6,7 +6,7 @@
class Agent;
typedef std::shared_ptr<Agent> AgentPtr;
using AgentPtr = std::shared_ptr<Agent>;
class Agent {
public:

View File

@ -48,6 +48,7 @@
#include "FileSystem.h"
#include "net/ApiDownload.h"
#include "net/ChecksumValidator.h"
#include "net/Download.h"
#include "Application.h"

View File

@ -105,4 +105,4 @@ class Component : public QObject, public ProblemProvider {
bool m_loaded = false;
};
typedef shared_qobject_ptr<Component> ComponentPtr;
using ComponentPtr = shared_qobject_ptr<Component>;

View File

@ -52,7 +52,7 @@
class Library;
class MinecraftInstance;
typedef std::shared_ptr<Library> LibraryPtr;
using LibraryPtr = std::shared_ptr<Library>;
class Library {
friend class OneSixVersionFormat;

View File

@ -188,6 +188,9 @@ void MinecraftInstance::loadSpecificSettings()
auto legacySettings = m_settings->registerSetting("OverrideLegacySettings", false);
m_settings->registerOverride(global_settings->getSetting("OnlineFixes"), legacySettings);
auto envSetting = m_settings->registerSetting("OverrideEnv", false);
m_settings->registerOverride(global_settings->getSetting("Env"), envSetting);
m_settings->set("InstanceType", "OneSix");
}
@ -548,6 +551,7 @@ QMap<QString, QString> MinecraftInstance::getVariables()
out.insert("INST_MC_DIR", QDir::toNativeSeparators(QDir(gameRoot()).absolutePath()));
out.insert("INST_JAVA", settings()->get("JavaPath").toString());
out.insert("INST_JAVA_ARGS", javaArguments().join(' '));
out.insert("NO_COLOR", "1");
return out;
}
@ -571,15 +575,20 @@ QProcessEnvironment MinecraftInstance::createLaunchEnvironment()
#ifdef Q_OS_LINUX
if (settings()->get("EnableMangoHud").toBool() && APPLICATION->capabilities() & Application::SupportsMangoHud) {
auto preloadList = env.value("LD_PRELOAD").split(QLatin1String(":"));
auto libPaths = env.value("LD_LIBRARY_PATH").split(QLatin1String(":"));
QStringList preloadList;
if (auto value = env.value("LD_PRELOAD"); !value.isEmpty())
preloadList = value.split(QLatin1String(":"));
QStringList libPaths;
if (auto value = env.value("LD_LIBRARY_PATH"); !value.isEmpty())
libPaths = value.split(QLatin1String(":"));
auto mangoHudLibString = MangoHud::getLibraryString();
if (!mangoHudLibString.isEmpty()) {
QFileInfo mangoHudLib(mangoHudLibString);
// dlsym variant is only needed for OpenGL and not included in the vulkan layer
preloadList << "libMangoHud_dlsym.so" << mangoHudLib.fileName();
preloadList << "libMangoHud_dlsym.so"
<< "libMangoHud_opengl.so" << mangoHudLib.fileName();
libPaths << mangoHudLib.absolutePath();
}
@ -598,6 +607,23 @@ QProcessEnvironment MinecraftInstance::createLaunchEnvironment()
}
#endif
// custom env
auto insertEnv = [&env](QMap<QString, QVariant> envMap) {
if (envMap.isEmpty())
return;
for (auto iter = envMap.begin(); iter != envMap.end(); iter++)
env.insert(iter.key(), iter.value().toString());
};
bool overrideEnv = settings()->get("OverrideEnv").toBool();
if (!overrideEnv)
insertEnv(APPLICATION->settings()->get("Env").toMap());
else
insertEnv(settings()->get("Env").toMap());
return env;
}
@ -710,7 +736,7 @@ QString MinecraftInstance::createLaunchScript(AuthSessionPtr session, MinecraftS
{
QString windowParams;
if (settings()->get("LaunchMaximized").toBool())
windowParams = "max";
windowParams = "maximized";
else
windowParams =
QString("%1x%2").arg(settings()->get("MinecraftWinWidth").toInt()).arg(settings()->get("MinecraftWinHeight").toInt());
@ -718,6 +744,19 @@ QString MinecraftInstance::createLaunchScript(AuthSessionPtr session, MinecraftS
launchScript += "windowParams " + windowParams + "\n";
}
// launcher info
{
launchScript += "launcherBrand " + BuildConfig.LAUNCHER_NAME + "\n";
launchScript += "launcherVersion " + BuildConfig.printableVersionString() + "\n";
}
// instance info
{
launchScript += "instanceName " + name() + "\n";
launchScript += "instanceIconKey " + name() + "\n";
launchScript += "instanceIconPath icon.png\n"; // we already save a copy here
}
// legacy auth
if (session) {
launchScript += "userName " + session->player_name + "\n";

View File

@ -174,4 +174,4 @@ class MinecraftInstance : public BaseInstance {
mutable std::shared_ptr<GameOptions> m_game_options;
};
typedef std::shared_ptr<MinecraftInstance> MinecraftInstancePtr;
using MinecraftInstancePtr = std::shared_ptr<MinecraftInstance>;

View File

@ -5,7 +5,7 @@
struct MojangDownloadInfo {
// types
typedef std::shared_ptr<MojangDownloadInfo> Ptr;
using Ptr = std::shared_ptr<MojangDownloadInfo>;
// data
/// Local filesystem path. WARNING: not used, only here so we can pass through mojang files unmolested!
@ -23,7 +23,7 @@ struct MojangLibraryDownloadInfo {
MojangLibraryDownloadInfo() {}
// types
typedef std::shared_ptr<MojangLibraryDownloadInfo> Ptr;
using Ptr = std::shared_ptr<MojangLibraryDownloadInfo>;
// methods
MojangDownloadInfo* getDownloadInfo(QString classifier)
@ -42,7 +42,7 @@ struct MojangLibraryDownloadInfo {
struct MojangAssetIndexInfo : public MojangDownloadInfo {
// types
typedef std::shared_ptr<MojangAssetIndexInfo> Ptr;
using Ptr = std::shared_ptr<MojangAssetIndexInfo>;
// methods
MojangAssetIndexInfo() {}

View File

@ -38,7 +38,7 @@
#include "VersionFile.h"
namespace ProfileUtils {
typedef QStringList PatchOrder;
using PatchOrder = QStringList;
/// Read and parse a OneSix format order file
bool readOverrideOrders(QString path, PatchOrder& order);

View File

@ -43,4 +43,4 @@ struct AuthSession {
bool demo = false;
};
typedef std::shared_ptr<AuthSession> AuthSessionPtr;
using AuthSessionPtr = std::shared_ptr<AuthSession>;

View File

@ -54,7 +54,7 @@ class Task;
class AccountTask;
class MinecraftAccount;
typedef shared_qobject_ptr<MinecraftAccount> MinecraftAccountPtr;
using MinecraftAccountPtr = shared_qobject_ptr<MinecraftAccount>;
Q_DECLARE_METATYPE(MinecraftAccountPtr)
/**

View File

@ -26,4 +26,4 @@ struct MinecraftServerTarget {
static MinecraftServerTarget parse(const QString& fullAddress);
};
typedef std::shared_ptr<MinecraftServerTarget> MinecraftServerTargetPtr;
using MinecraftServerTargetPtr = std::shared_ptr<MinecraftServerTarget>;

View File

@ -38,9 +38,9 @@
#include "ModFolderModel.h"
#include <FileSystem.h>
#include <qheaderview.h>
#include <QDebug>
#include <QFileSystemWatcher>
#include <QHeaderView>
#include <QIcon>
#include <QMimeData>
#include <QString>
@ -71,10 +71,9 @@ ModFolderModel::ModFolderModel(const QString& dir, BaseInstance* instance, bool
tr("Side"), tr("Loaders"), tr("Miecraft Versions"), tr("Release Type") });
m_column_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::NAME, SortType::VERSION, SortType::DATE,
SortType::PROVIDER, SortType::SIDE, SortType::LOADERS, SortType::MC_VERSIONS, SortType::RELEASE_TYPE };
m_column_resize_modes = { QHeaderView::ResizeToContents, QHeaderView::Interactive, QHeaderView::Stretch,
QHeaderView::ResizeToContents, QHeaderView::ResizeToContents, QHeaderView::ResizeToContents,
QHeaderView::ResizeToContents, QHeaderView::ResizeToContents, QHeaderView::ResizeToContents,
QHeaderView::ResizeToContents };
m_column_resize_modes = { QHeaderView::Interactive, QHeaderView::Interactive, QHeaderView::Stretch, QHeaderView::Interactive,
QHeaderView::Interactive, QHeaderView::Interactive, QHeaderView::Interactive, QHeaderView::Interactive,
QHeaderView::Interactive, QHeaderView::Interactive };
m_columnsHideable = { false, true, false, true, true, true, true, true, true, true };
}
@ -159,6 +158,11 @@ QVariant ModFolderModel::data(const QModelIndex& index, int role) const
}
return {};
}
case Qt::SizeHintRole:
if (column == ImageColumn) {
return QSize(32, 32);
}
return {};
case Qt::CheckStateRole:
switch (column) {
case ActiveColumn:

View File

@ -4,6 +4,7 @@
#include <QCoreApplication>
#include <QDebug>
#include <QFileInfo>
#include <QHeaderView>
#include <QIcon>
#include <QMenu>
#include <QMimeData>
@ -516,36 +517,22 @@ void ResourceFolderModel::setupHeaderAction(QAction* act, int column)
act->setText(columnNames().at(column));
}
void ResourceFolderModel::saveHiddenColumn(int column, bool hidden)
void ResourceFolderModel::saveColumns(QTreeView* tree)
{
auto const setting_name = QString("UI/%1_Page/HiddenColumns").arg(id());
auto const setting_name = QString("UI/%1_Page/Columns").arg(id());
auto setting = (m_instance->settings()->contains(setting_name)) ? m_instance->settings()->getSetting(setting_name)
: m_instance->settings()->registerSetting(setting_name);
auto hiddenColumns = setting->get().toStringList();
auto name = columnNames(false).at(column);
auto index = hiddenColumns.indexOf(name);
if (index >= 0 && !hidden) {
hiddenColumns.removeAt(index);
} else if (index < 0 && hidden) {
hiddenColumns.append(name);
}
setting->set(hiddenColumns);
setting->set(tree->header()->saveState());
}
void ResourceFolderModel::loadHiddenColumns(QTreeView* tree)
void ResourceFolderModel::loadColumns(QTreeView* tree)
{
auto const setting_name = QString("UI/%1_Page/HiddenColumns").arg(id());
auto const setting_name = QString("UI/%1_Page/Columns").arg(id());
auto setting = (m_instance->settings()->contains(setting_name)) ? m_instance->settings()->getSetting(setting_name)
: m_instance->settings()->registerSetting(setting_name);
auto hiddenColumns = setting->get().toStringList();
auto col_names = columnNames(false);
for (auto col_name : hiddenColumns) {
auto index = col_names.indexOf(col_name);
if (index >= 0)
tree->setColumnHidden(index, true);
}
tree->header()->restoreState(setting->get().toByteArray());
}
QMenu* ResourceFolderModel::createHeaderContextMenu(QTreeView* tree)
@ -570,7 +557,7 @@ QMenu* ResourceFolderModel::createHeaderContextMenu(QTreeView* tree)
if (m_column_resize_modes.at(c) == QHeaderView::ResizeToContents)
tree->resizeColumnToContents(c);
}
saveHiddenColumn(col, !toggled);
saveColumns(tree);
});
menu->addAction(act);

View File

@ -117,8 +117,8 @@ class ResourceFolderModel : public QAbstractListModel {
[[nodiscard]] QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
void setupHeaderAction(QAction* act, int column);
void saveHiddenColumn(int column, bool hidden);
void loadHiddenColumns(QTreeView* tree);
void saveColumns(QTreeView* tree);
void loadColumns(QTreeView* tree);
QMenu* createHeaderContextMenu(QTreeView* tree);
/** This creates a proxy model to filter / sort the model for a UI.
@ -201,8 +201,7 @@ class ResourceFolderModel : public QAbstractListModel {
QList<SortType> m_column_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::DATE };
QStringList m_column_names = { "Enable", "Name", "Last Modified" };
QStringList m_column_names_translated = { tr("Enable"), tr("Name"), tr("Last Modified") };
QList<QHeaderView::ResizeMode> m_column_resize_modes = { QHeaderView::ResizeToContents, QHeaderView::Stretch,
QHeaderView::ResizeToContents };
QList<QHeaderView::ResizeMode> m_column_resize_modes = { QHeaderView::Interactive, QHeaderView::Stretch, QHeaderView::Interactive };
QList<bool> m_columnsHideable = { false, false, true };
QDir m_dir;

View File

@ -52,8 +52,8 @@ ResourcePackFolderModel::ResourcePackFolderModel(const QString& dir, BaseInstanc
m_column_names = QStringList({ "Enable", "Image", "Name", "Pack Format", "Last Modified" });
m_column_names_translated = QStringList({ tr("Enable"), tr("Image"), tr("Name"), tr("Pack Format"), tr("Last Modified") });
m_column_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::NAME, SortType::PACK_FORMAT, SortType::DATE };
m_column_resize_modes = { QHeaderView::ResizeToContents, QHeaderView::Interactive, QHeaderView::Stretch, QHeaderView::ResizeToContents,
QHeaderView::ResizeToContents };
m_column_resize_modes = { QHeaderView::Interactive, QHeaderView::Interactive, QHeaderView::Stretch, QHeaderView::Interactive,
QHeaderView::Interactive };
m_columnsHideable = { false, true, false, true, true };
}
@ -117,6 +117,11 @@ QVariant ResourcePackFolderModel::data(const QModelIndex& index, int role) const
}
return m_resources[row]->internal_id();
}
case Qt::SizeHintRole:
if (column == ImageColumn) {
return QSize(32, 32);
}
return {};
case Qt::CheckStateRole:
switch (column) {
case ActiveColumn:

View File

@ -47,8 +47,7 @@ TexturePackFolderModel::TexturePackFolderModel(const QString& dir, BaseInstance*
m_column_names = QStringList({ "Enable", "Image", "Name", "Last Modified" });
m_column_names_translated = QStringList({ tr("Enable"), tr("Image"), tr("Name"), tr("Last Modified") });
m_column_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::NAME, SortType::DATE };
m_column_resize_modes = { QHeaderView::ResizeToContents, QHeaderView::Interactive, QHeaderView::Stretch,
QHeaderView::ResizeToContents };
m_column_resize_modes = { QHeaderView::Interactive, QHeaderView::Interactive, QHeaderView::Stretch, QHeaderView::Interactive };
m_columnsHideable = { false, true, false, true };
}
@ -104,6 +103,11 @@ QVariant TexturePackFolderModel::data(const QModelIndex& index, int role) const
}
return {};
}
case Qt::SizeHintRole:
if (column == ImageColumn) {
return QSize(32, 32);
}
return {};
case Qt::CheckStateRole:
if (column == ActiveColumn) {
return m_resources[row]->enabled() ? Qt::Checked : Qt::Unchecked;

View File

@ -688,6 +688,7 @@ bool loadIconFile(const Mod& mod)
return png_invalid(); // icon invalid
}
}
return false;
}
case ResourceType::ZIPFILE: {
QuaZip zip(mod.fileinfo().filePath());
@ -714,6 +715,7 @@ bool loadIconFile(const Mod& mod)
} else {
return png_invalid(); // could not set icon as current file.
}
return false;
}
case ResourceType::LITEMOD: {
return false; // can lightmods even have icons?

View File

@ -232,10 +232,9 @@ bool processPackPNG(const ResourcePack& pack)
} else {
return png_invalid(); // pack.png does not exists or is not a valid file.
}
return false; // not processed correctly; https://github.com/PrismLauncher/PrismLauncher/issues/1740
}
case ResourceType::ZIPFILE: {
Q_ASSERT(pack.type() == ResourceType::ZIPFILE);
QuaZip zip(pack.fileinfo().filePath());
if (!zip.open(QuaZip::mdUnzip))
return false; // can't open zip file
@ -259,6 +258,7 @@ bool processPackPNG(const ResourcePack& pack)
} else {
return png_invalid(); // could not set pack.mcmeta as current file.
}
return false; // not processed correctly; https://github.com/PrismLauncher/PrismLauncher/issues/1740
}
default:
qWarning() << "Invalid type for resource pack parse task!";

View File

@ -186,10 +186,9 @@ bool processPackPNG(const TexturePack& pack)
} else {
return png_invalid(); // pack.png does not exists or is not a valid file.
}
return false;
}
case ResourceType::ZIPFILE: {
Q_ASSERT(pack.type() == ResourceType::ZIPFILE);
QuaZip zip(pack.fileinfo().filePath());
if (!zip.open(QuaZip::mdUnzip))
return false; // can't open zip file
@ -215,6 +214,7 @@ bool processPackPNG(const TexturePack& pack)
zip.close();
return png_invalid(); // could not set pack.mcmeta as current file.
}
return false;
}
default:
qWarning() << "Invalid type for resource pack parse task!";

View File

@ -4,7 +4,7 @@
#include <QtNetwork/QtNetwork>
#include "tasks/Task.h"
typedef shared_qobject_ptr<class SkinDelete> SkinDeletePtr;
using SkinDeletePtr = shared_qobject_ptr<class SkinDelete>;
class SkinDelete : public Task {
Q_OBJECT

View File

@ -5,7 +5,7 @@
#include <memory>
#include "tasks/Task.h"
typedef shared_qobject_ptr<class SkinUpload> SkinUploadPtr;
using SkinUploadPtr = shared_qobject_ptr<class SkinUpload>;
class SkinUpload : public Task {
Q_OBJECT

View File

@ -210,19 +210,17 @@ Task::Ptr FlameAPI::getFile(const QString& addonId, const QString& fileId, std::
return netJob;
}
// https://docs.curseforge.com/?python#tocS_ModsSearchSortField
static QList<ResourceAPI::SortingMethod> s_sorts = { { 1, "Featured", QObject::tr("Sort by Featured") },
{ 2, "Popularity", QObject::tr("Sort by Popularity") },
{ 3, "LastUpdated", QObject::tr("Sort by Last Updated") },
{ 4, "Name", QObject::tr("Sort by Name") },
{ 5, "Author", QObject::tr("Sort by Author") },
{ 6, "TotalDownloads", QObject::tr("Sort by Downloads") },
{ 7, "Category", QObject::tr("Sort by Category") },
{ 8, "GameVersion", QObject::tr("Sort by Game Version") } };
QList<ResourceAPI::SortingMethod> FlameAPI::getSortingMethods() const
{
return s_sorts;
// https://docs.curseforge.com/?python#tocS_ModsSearchSortField
return { { 1, "Featured", QObject::tr("Sort by Featured") },
{ 2, "Popularity", QObject::tr("Sort by Popularity") },
{ 3, "LastUpdated", QObject::tr("Sort by Last Updated") },
{ 4, "Name", QObject::tr("Sort by Name") },
{ 5, "Author", QObject::tr("Sort by Author") },
{ 6, "TotalDownloads", QObject::tr("Sort by Downloads") },
{ 7, "Category", QObject::tr("Sort by Category") },
{ 8, "GameVersion", QObject::tr("Sort by Game Version") } };
}
Task::Ptr FlameAPI::getModCategories(std::shared_ptr<QByteArray> response)

View File

@ -45,7 +45,7 @@ struct Modpack {
QIcon icon;
};
typedef QList<Modpack> ModpackList;
using ModpackList = QList<Modpack>;
Modpack parseDirectory(QString path);

View File

@ -31,7 +31,7 @@ struct Modpack {
QString packCode;
};
typedef QList<Modpack> ModpackList;
using ModpackList = QList<Modpack>;
} // namespace LegacyFTB

View File

@ -111,16 +111,14 @@ Task::Ptr ModrinthAPI::getProjects(QStringList addonIds, std::shared_ptr<QByteAr
return netJob;
}
// https://docs.modrinth.com/api-spec/#tag/projects/operation/searchProjects
static QList<ResourceAPI::SortingMethod> s_sorts = { { 1, "relevance", QObject::tr("Sort by Relevance") },
{ 2, "downloads", QObject::tr("Sort by Downloads") },
{ 3, "follows", QObject::tr("Sort by Follows") },
{ 4, "newest", QObject::tr("Sort by Last Updated") },
{ 5, "updated", QObject::tr("Sort by Newest") } };
QList<ResourceAPI::SortingMethod> ModrinthAPI::getSortingMethods() const
{
return s_sorts;
// https://docs.modrinth.com/api-spec/#tag/projects/operation/searchProjects
return { { 1, "relevance", QObject::tr("Sort by Relevance") },
{ 2, "downloads", QObject::tr("Sort by Downloads") },
{ 3, "follows", QObject::tr("Sort by Follows") },
{ 4, "newest", QObject::tr("Sort by Newest") },
{ 5, "updated", QObject::tr("Sort by Last Updated") } };
}
Task::Ptr ModrinthAPI::getModCategories(std::shared_ptr<QByteArray> response)

View File

@ -112,6 +112,8 @@ void NetRequest::executeTask()
m_last_progress_bytes = 0;
QNetworkReply* rep = getReply(request);
if (rep == nullptr) // it failed
return;
m_reply.reset(rep);
connect(rep, &QNetworkReply::downloadProgress, this, &NetRequest::downloadProgress);
connect(rep, &QNetworkReply::finished, this, &NetRequest::downloadFinished);

View File

@ -87,7 +87,7 @@ class NetRequest : public NetAction {
std::unique_ptr<Sink> m_sink;
Options m_options;
typedef const QLoggingCategory& (*logCatFunc)();
using logCatFunc = const QLoggingCategory& (*)();
logCatFunc logCat = taskUploadLogC;
std::chrono::steady_clock m_clock;

View File

@ -0,0 +1,39 @@
// SPDX-License-Identifier: GPL-3.0-only
/*
* Prism Launcher - Minecraft Launcher
* Copyright (C) 2023 Rachel Powers <508861+Ryex@users.noreply.github.com>
*
* 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 <https://www.gnu.org/licenses/>.
*
*/
#pragma once
#include "net/HeaderProxy.h"
namespace Net {
class StaticHeaderProxy : public HeaderProxy {
public:
StaticHeaderProxy(QList<HeaderPair> hdrs = {}) : HeaderProxy(), m_hdrs(hdrs){};
virtual ~StaticHeaderProxy() = default;
public:
virtual QList<HeaderPair> headers(const QNetworkRequest&) const override { return m_hdrs; };
void setHeaders(QList<HeaderPair> hdrs) { m_hdrs = hdrs; };
private:
QList<HeaderPair> m_hdrs;
};
} // namespace Net

View File

@ -51,4 +51,4 @@ class NewsEntry : public QObject {
QString link;
};
typedef std::shared_ptr<NewsEntry> NewsEntryPtr;
using NewsEntryPtr = std::shared_ptr<NewsEntry>;

View File

@ -4,7 +4,7 @@
class IPathMatcher {
public:
typedef std::shared_ptr<IPathMatcher> Ptr;
using Ptr = std::shared_ptr<IPathMatcher>;
public:
virtual ~IPathMatcher() {}

View File

@ -9,6 +9,7 @@
<file>scalable/copy.svg</file>
<file>scalable/coremods.svg</file>
<file>scalable/custom-commands.svg</file>
<file>scalable/environment-variables.svg</file>
<file>scalable/discord.svg</file>
<file>scalable/externaltools.svg</file>
<file>scalable/help.svg</file>

View File

@ -0,0 +1,13 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
<defs id="defs3051">
<style type="text/css" id="current-color-scheme">
.ColorScheme-Text {
color:#eff0f1;
}
</style>
</defs>
<path style="fill:currentColor;fill-opacity:1;stroke:none"
d="M 6 2 C 4.895478 2 4 2.8954778 4 4 L 4 6 L 4 7 C 4 7.2761493 3.7761423 7.5 3.5 7.5 L 3 7.5 L 3 8.5 L 3.5 8.5 C 3.7761423 8.5 4 8.7238507 4 9 L 4 10 L 4 11 L 4 12 C 4 13.104597 4.8954307 14 6 14 L 7 14 L 7 13 L 6 13 C 5.4477157 13 5 12.552299 5 12 L 5 11 L 5 10 L 5 9 C 5 8.617501 4.8607153 8.2649743 4.625 8 C 4.8607153 7.7350257 5 7.382499 5 7 L 5 6 L 5 5.71875 L 5 4 C 5 3.4477014 5.4477765 3 6 3 L 7 3 L 7 2 L 6 2 z M 9 2 L 9 3 L 10 3 C 10.552224 3 11 3.4477014 11 4 L 11 5.71875 L 11 6 L 11 7 C 11 7.382499 11.139285 7.7350257 11.375 8 C 11.139285 8.2649743 11 8.617501 11 9 L 11 10 L 11 11 L 11 12 C 11 12.552299 10.552284 13 10 13 L 9 13 L 9 14 L 10 14 C 11.104569 14 12 13.104597 12 12 L 12 11 L 12 10 L 12 9 C 12 8.7238507 12.223858 8.5 12.5 8.5 L 13 8.5 L 13 7.5 L 12.5 7.5 C 12.223858 7.5 12 7.2761493 12 7 L 12 6 L 12 4 C 12 2.8954778 11.104522 2 10 2 L 9 2 z "
class="ColorScheme-Text"
/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -9,6 +9,7 @@
<file>scalable/copy.svg</file>
<file>scalable/coremods.svg</file>
<file>scalable/custom-commands.svg</file>
<file>scalable/environment-variables.svg</file>
<file>scalable/discord.svg</file>
<file>scalable/externaltools.svg</file>
<file>scalable/help.svg</file>

View File

@ -0,0 +1,13 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
<defs id="defs3051">
<style type="text/css" id="current-color-scheme">
.ColorScheme-Text {
color:#232629;
}
</style>
</defs>
<path style="fill:currentColor;fill-opacity:1;stroke:none"
d="M 6 2 C 4.895478 2 4 2.8954778 4 4 L 4 6 L 4 7 C 4 7.2761493 3.7761423 7.5 3.5 7.5 L 3 7.5 L 3 8.5 L 3.5 8.5 C 3.7761423 8.5 4 8.7238507 4 9 L 4 10 L 4 11 L 4 12 C 4 13.104597 4.8954307 14 6 14 L 7 14 L 7 13 L 6 13 C 5.4477157 13 5 12.552299 5 12 L 5 11 L 5 10 L 5 9 C 5 8.617501 4.8607153 8.2649743 4.625 8 C 4.8607153 7.7350257 5 7.382499 5 7 L 5 6 L 5 5.71875 L 5 4 C 5 3.4477014 5.4477765 3 6 3 L 7 3 L 7 2 L 6 2 z M 9 2 L 9 3 L 10 3 C 10.552224 3 11 3.4477014 11 4 L 11 5.71875 L 11 6 L 11 7 C 11 7.382499 11.139285 7.7350257 11.375 8 C 11.139285 8.2649743 11 8.617501 11 9 L 11 10 L 11 11 L 11 12 C 11 12.552299 10.552284 13 10 13 L 9 13 L 9 14 L 10 14 C 11.104569 14 12 13.104597 12 12 L 12 11 L 12 10 L 12 9 C 12 8.7238507 12.223858 8.5 12.5 8.5 L 13 8.5 L 13 7.5 L 12.5 7.5 C 12.223858 7.5 12 7.2761493 12 7 L 12 6 L 12 4 C 12 2.8954778 11.104522 2 10 2 L 9 2 z "
class="ColorScheme-Text"
/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -11,6 +11,7 @@
<file>scalable/copy.svg</file>
<file>scalable/coremods.svg</file>
<file>scalable/custom-commands.svg</file>
<file>scalable/environment-variables.svg</file>
<file>scalable/discord.svg</file>
<file>scalable/externaltools.svg</file>
<file>scalable/help.svg</file>

View File

@ -1,86 +1 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
fill="#757575"
height="24"
viewBox="0 0 24 24"
width="24"
version="1.1"
id="svg4"
sodipodi:docname="custom-commands.svg"
inkscape:version="1.1 (c4e8f9ed74, 2021-05-24)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<metadata
id="metadata10">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs8" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="3440"
inkscape:window-height="1382"
id="namedview6"
showgrid="true"
showguides="true"
inkscape:guide-bbox="true"
inkscape:zoom="39.333333"
inkscape:cx="11.38983"
inkscape:cy="13.283898"
inkscape:window-x="0"
inkscape:window-y="32"
inkscape:window-maximized="1"
inkscape:current-layer="svg4"
inkscape:pagecheckerboard="0">
<inkscape:grid
type="xygrid"
id="grid981" />
<sodipodi:guide
position="-8,11.440678"
orientation="1,0"
id="guide1060"
inkscape:locked="false" />
<sodipodi:guide
position="-28.34375,24"
orientation="0,1"
id="guide1062"
inkscape:locked="false" />
</sodipodi:namedview>
<g
style="fill:#000000"
id="g821"
transform="matrix(0.0322459,0,0,0.0322459,-17.878956,30.647558)">
<g
style="fill:#000000"
id="g819" />
</g>
<g
id="g503">
<path
d="M 0,0 H 24 V 24 H 0 Z"
fill="none"
id="path491" />
<path
d="M 8.7,15.9 4.8,12 8.7,8.1 C 9.09,7.71 9.09,7.09 8.7,6.7 8.31,6.31 7.69,6.31 7.3,6.7 l -4.59,4.59 c -0.39,0.39 -0.39,1.02 0,1.41 l 4.59,4.6 c 0.39,0.39 1.01,0.39 1.4,0 0.39,-0.39 0.39,-1.01 0,-1.4 z m 6.6,0 3.9,-3.9 -3.9,-3.9 c -0.39,-0.39 -0.39,-1.01 0,-1.4 0.39,-0.39 1.01,-0.39 1.4,0 l 4.59,4.59 c 0.39,0.39 0.39,1.02 0,1.41 l -4.59,4.6 c -0.39,0.39 -1.01,0.39 -1.4,0 -0.39,-0.39 -0.39,-1.01 0,-1.4 z"
id="path493" />
</g>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#757575"><g><rect fill="none" height="24" width="24"/></g><g><path d="M20,4H4C2.89,4,2,4.9,2,6v12c0,1.1,0.89,2,2,2h16c1.1,0,2-0.9,2-2V6C22,4.9,21.11,4,20,4z M20,18H4V8h16V18z M18,17h-6v-2 h6V17z M7.5,17l-1.41-1.41L8.67,13l-2.59-2.59L7.5,9l4,4L7.5,17z"/></g></svg>

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 391 B

View File

@ -0,0 +1,86 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
fill="#757575"
height="24"
viewBox="0 0 24 24"
width="24"
version="1.1"
id="svg4"
sodipodi:docname="custom-commands.svg"
inkscape:version="1.1 (c4e8f9ed74, 2021-05-24)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<metadata
id="metadata10">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs8" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="3440"
inkscape:window-height="1382"
id="namedview6"
showgrid="true"
showguides="true"
inkscape:guide-bbox="true"
inkscape:zoom="39.333333"
inkscape:cx="11.38983"
inkscape:cy="13.283898"
inkscape:window-x="0"
inkscape:window-y="32"
inkscape:window-maximized="1"
inkscape:current-layer="svg4"
inkscape:pagecheckerboard="0">
<inkscape:grid
type="xygrid"
id="grid981" />
<sodipodi:guide
position="-8,11.440678"
orientation="1,0"
id="guide1060"
inkscape:locked="false" />
<sodipodi:guide
position="-28.34375,24"
orientation="0,1"
id="guide1062"
inkscape:locked="false" />
</sodipodi:namedview>
<g
style="fill:#000000"
id="g821"
transform="matrix(0.0322459,0,0,0.0322459,-17.878956,30.647558)">
<g
style="fill:#000000"
id="g819" />
</g>
<g
id="g503">
<path
d="M 0,0 H 24 V 24 H 0 Z"
fill="none"
id="path491" />
<path
d="M 8.7,15.9 4.8,12 8.7,8.1 C 9.09,7.71 9.09,7.09 8.7,6.7 8.31,6.31 7.69,6.31 7.3,6.7 l -4.59,4.59 c -0.39,0.39 -0.39,1.02 0,1.41 l 4.59,4.6 c 0.39,0.39 1.01,0.39 1.4,0 0.39,-0.39 0.39,-1.01 0,-1.4 z m 6.6,0 3.9,-3.9 -3.9,-3.9 c -0.39,-0.39 -0.39,-1.01 0,-1.4 0.39,-0.39 1.01,-0.39 1.4,0 l 4.59,4.59 c 0.39,0.39 0.39,1.02 0,1.41 l -4.59,4.6 c -0.39,0.39 -1.01,0.39 -1.4,0 -0.39,-0.39 -0.39,-1.01 0,-1.4 z"
id="path493" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@ -11,6 +11,7 @@
<file>scalable/copy.svg</file>
<file>scalable/coremods.svg</file>
<file>scalable/custom-commands.svg</file>
<file>scalable/environment-variables.svg</file>
<file>scalable/discord.svg</file>
<file>scalable/externaltools.svg</file>
<file>scalable/help.svg</file>

View File

@ -1,86 +1 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
fill="#eeeeee"
height="24"
viewBox="0 0 24 24"
width="24"
version="1.1"
id="svg4"
sodipodi:docname="custom-commands.svg"
inkscape:version="1.1 (c4e8f9ed74, 2021-05-24)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<metadata
id="metadata10">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs8" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="3440"
inkscape:window-height="1382"
id="namedview6"
showgrid="true"
showguides="true"
inkscape:guide-bbox="true"
inkscape:zoom="39.333333"
inkscape:cx="11.38983"
inkscape:cy="13.283898"
inkscape:window-x="0"
inkscape:window-y="32"
inkscape:window-maximized="1"
inkscape:current-layer="svg4"
inkscape:pagecheckerboard="0">
<inkscape:grid
type="xygrid"
id="grid981" />
<sodipodi:guide
position="-8,11.440678"
orientation="1,0"
id="guide1060"
inkscape:locked="false" />
<sodipodi:guide
position="-28.34375,24"
orientation="0,1"
id="guide1062"
inkscape:locked="false" />
</sodipodi:namedview>
<g
style="fill:#000000"
id="g821"
transform="matrix(0.0322459,0,0,0.0322459,-17.878956,30.647558)">
<g
style="fill:#000000"
id="g819" />
</g>
<g
id="g503">
<path
d="M 0,0 H 24 V 24 H 0 Z"
fill="none"
id="path491" />
<path
d="M 8.7,15.9 4.8,12 8.7,8.1 C 9.09,7.71 9.09,7.09 8.7,6.7 8.31,6.31 7.69,6.31 7.3,6.7 l -4.59,4.59 c -0.39,0.39 -0.39,1.02 0,1.41 l 4.59,4.6 c 0.39,0.39 1.01,0.39 1.4,0 0.39,-0.39 0.39,-1.01 0,-1.4 z m 6.6,0 3.9,-3.9 -3.9,-3.9 c -0.39,-0.39 -0.39,-1.01 0,-1.4 0.39,-0.39 1.01,-0.39 1.4,0 l 4.59,4.59 c 0.39,0.39 0.39,1.02 0,1.41 l -4.59,4.6 c -0.39,0.39 -1.01,0.39 -1.4,0 -0.39,-0.39 -0.39,-1.01 0,-1.4 z"
id="path493" />
</g>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#eeeeee"><g><rect fill="none" height="24" width="24"/></g><g><path d="M20,4H4C2.89,4,2,4.9,2,6v12c0,1.1,0.89,2,2,2h16c1.1,0,2-0.9,2-2V6C22,4.9,21.11,4,20,4z M20,18H4V8h16V18z M18,17h-6v-2 h6V17z M7.5,17l-1.41-1.41L8.67,13l-2.59-2.59L7.5,9l4,4L7.5,17z"/></g></svg>

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 391 B

View File

@ -0,0 +1,86 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
fill="#eeeeee"
height="24"
viewBox="0 0 24 24"
width="24"
version="1.1"
id="svg4"
sodipodi:docname="custom-commands.svg"
inkscape:version="1.1 (c4e8f9ed74, 2021-05-24)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<metadata
id="metadata10">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs8" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="3440"
inkscape:window-height="1382"
id="namedview6"
showgrid="true"
showguides="true"
inkscape:guide-bbox="true"
inkscape:zoom="39.333333"
inkscape:cx="11.38983"
inkscape:cy="13.283898"
inkscape:window-x="0"
inkscape:window-y="32"
inkscape:window-maximized="1"
inkscape:current-layer="svg4"
inkscape:pagecheckerboard="0">
<inkscape:grid
type="xygrid"
id="grid981" />
<sodipodi:guide
position="-8,11.440678"
orientation="1,0"
id="guide1060"
inkscape:locked="false" />
<sodipodi:guide
position="-28.34375,24"
orientation="0,1"
id="guide1062"
inkscape:locked="false" />
</sodipodi:namedview>
<g
style="fill:#000000"
id="g821"
transform="matrix(0.0322459,0,0,0.0322459,-17.878956,30.647558)">
<g
style="fill:#000000"
id="g819" />
</g>
<g
id="g503">
<path
d="M 0,0 H 24 V 24 H 0 Z"
fill="none"
id="path491" />
<path
d="M 8.7,15.9 4.8,12 8.7,8.1 C 9.09,7.71 9.09,7.09 8.7,6.7 8.31,6.31 7.69,6.31 7.3,6.7 l -4.59,4.59 c -0.39,0.39 -0.39,1.02 0,1.41 l 4.59,4.6 c 0.39,0.39 1.01,0.39 1.4,0 0.39,-0.39 0.39,-1.01 0,-1.4 z m 6.6,0 3.9,-3.9 -3.9,-3.9 c -0.39,-0.39 -0.39,-1.01 0,-1.4 0.39,-0.39 1.01,-0.39 1.4,0 l 4.59,4.59 c 0.39,0.39 0.39,1.02 0,1.41 l -4.59,4.6 c -0.39,0.39 -1.01,0.39 -1.4,0 -0.39,-0.39 -0.39,-1.01 0,-1.4 z"
id="path493" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@ -73,8 +73,8 @@
<file>64x64/screenshots.png</file>
<file>scalable/screenshots.svg</file>
<!-- Custom commands. -->
<file>scalable/custom-commands.svg</file>
<file>scalable/environment-variables.svg</file>
<!-- The cat button. Freeware, http://findicons.com/icon/73096/black_cat -->
<file>16x16/cat.png</file>

File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 113 KiB

View File

@ -0,0 +1,346 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="128"
height="128"
id="svg2"
sodipodi:version="0.32"
inkscape:version="0.47pre3 r22311"
version="1.0"
sodipodi:docname="code-context.svgz"
inkscape:output_extension="org.inkscape.output.svgz.inkscape"
inkscape:export-filename="/home/pinheiro/pics/oxygen-icons/scalable/actions/small/48x48/context.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90">
<defs
id="defs4">
<linearGradient
inkscape:collect="always"
id="linearGradient5440">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop5442" />
<stop
style="stop-color:#ffffff;stop-opacity:0;"
offset="1"
id="stop5444" />
</linearGradient>
<linearGradient
id="linearGradient5342">
<stop
style="stop-color:#232221;stop-opacity:1;"
offset="0"
id="stop5344" />
<stop
id="stop5394"
offset="0.10646833"
style="stop-color:#555350;stop-opacity:1;" />
<stop
style="stop-color:#918d88;stop-opacity:1;"
offset="1"
id="stop5346" />
</linearGradient>
<linearGradient
id="linearGradient3857"
inkscape:collect="always">
<stop
id="stop3859"
offset="0"
style="stop-color:#ffffff;stop-opacity:1;" />
<stop
id="stop3861"
offset="1"
style="stop-color:#ffffff;stop-opacity:0" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5342"
id="linearGradient5348"
x1="80.151077"
y1="-120.00011"
x2="80.151077"
y2="-15.919633"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.85712143,0,0,0.85712149,15.99961,-9.1458159)" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3857"
id="linearGradient5378"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.85712141,0,0,-0.85442216,15.99961,9.407114)"
x1="76"
y1="-4"
x2="76"
y2="-124" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3857"
id="radialGradient5386"
cx="64"
cy="136"
fx="64"
fy="136"
r="48"
gradientTransform="matrix(1.3086619,0,0,0.65227042,-19.755964,19.661784)"
gradientUnits="userSpaceOnUse" />
<filter
inkscape:collect="always"
id="filter5416"
x="-0.21917803"
width="1.4383561"
y="-0.21917814"
height="1.4383563">
<feGaussianBlur
inkscape:collect="always"
stdDeviation="1.4611876"
id="feGaussianBlur5418" />
</filter>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath5420">
<path
style="fill:url(#radialGradient5424);fill-opacity:1;stroke:none"
d="m 108,8 c -52,0 -36,4 0,4 3.57143,0 8,2.700959 8,8 0,24 4,24 4,0 0,-5.923499 -4.70207,-12 -12,-12 z"
id="path5422"
sodipodi:nodetypes="ccccc" />
</clipPath>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3857"
id="radialGradient5424"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.70743936,0.70677405,-0.99807448,0.99901401,48.73805,-79.148369)"
cx="112.00771"
cy="15.99981"
fx="112.00771"
fy="15.99981"
r="8.0077057" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3857"
id="radialGradient5426"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.70727305,0.70694048,-1.9971123,1.9980518,64.741093,-95.151426)"
cx="112.00771"
cy="15.99981"
fx="112.00771"
fy="15.99981"
r="8.0077057" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3857"
id="radialGradient5430"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.70727305,0.70694048,-1.9971123,1.9980518,64.741093,-95.151426)"
cx="112.00771"
cy="15.99981"
fx="112.00771"
fy="15.99981"
r="8.0077057" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3857"
id="radialGradient5436"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.70727305,0.70694048,-1.9971123,1.9980518,64.741093,-95.151426)"
cx="112.00771"
cy="15.99981"
fx="112.00771"
fy="15.99981"
r="8.0077057" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3857"
id="radialGradient5438"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.70727305,0.70694048,-1.9971123,1.9980518,64.741093,-95.151426)"
cx="112.00771"
cy="15.99981"
fx="112.00771"
fy="15.99981"
r="8.0077057" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5440"
id="linearGradient5451"
gradientUnits="userSpaceOnUse"
x1="71.937897"
y1="31.666744"
x2="71.937897"
y2="184.00002"
gradientTransform="matrix(0.49730883,0,0,0.49574271,32.172236,26.323555)" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3857"
id="linearGradient5453"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.85712141,0,0,-0.85442216,15.99961,9.25759)"
x1="76"
y1="-8"
x2="76"
y2="-72.117546" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3857"
id="radialGradient5480"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.70727305,0.70694048,-1.9971123,1.9980518,64.741093,-95.151426)"
cx="112.00771"
cy="15.99981"
fx="112.00771"
fy="15.99981"
r="8.0077057" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3857"
id="radialGradient5482"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.70727305,0.70694048,-1.9971123,1.9980518,64.741093,-95.151426)"
cx="112.00771"
cy="15.99981"
fx="112.00771"
fy="15.99981"
r="8.0077057" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
gridtolerance="10000"
guidetolerance="10"
objecttolerance="10"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="3.4029514"
inkscape:cx="135.41032"
inkscape:cy="66.337315"
inkscape:document-units="px"
inkscape:current-layer="layer1"
width="128px"
height="128px"
showgrid="true"
inkscape:window-width="1040"
inkscape:window-height="728"
inkscape:window-x="374"
inkscape:window-y="333"
showguides="true"
inkscape:guide-bbox="true"
inkscape:snap-nodes="false"
inkscape:snap-bbox="true"
inkscape:window-maximized="0">
<inkscape:grid
id="GridFromPre046Settings"
type="xygrid"
originx="0px"
originy="0px"
spacingx="2.6666px"
spacingy="2.6666px"
color="#0000ff"
empcolor="#0000ff"
opacity="0.2"
empopacity="0.4"
empspacing="2"
visible="true"
enabled="true" />
</sodipodi:namedview>
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<rect
style="fill:url(#linearGradient5348);fill-opacity:1;stroke:none"
id="rect3888"
width="95.997589"
height="95.997597"
x="15.999609"
y="-112.0004"
rx="10.285457"
ry="10.285458"
transform="scale(1,-1)" />
<path
style="opacity:0.60465118;fill:url(#linearGradient5453);fill-opacity:1;stroke:none"
d="m 25.485068,18.710656 c -3.798763,0 -6.856972,3.048578 -6.856972,6.835377 l 0.8,37.219744 c 6.539821,0.759062 16.86475,1.174831 23.9994,1.174831 25.561145,0 52.250262,-5.22011 65.841214,-13.190143 l 0,-25.104432 c 0,-3.786799 -3.05819,-6.835377 -6.85697,-6.835377 l -76.926672,-0.1 z"
id="rect5352"
sodipodi:nodetypes="cccscccc" />
<path
style="font-size:113.80991364px;fill:url(#linearGradient5451);fill-opacity:1"
d="m 56.043058,38.22138 c -4.502355,0.02208 -8.022848,0.601203 -9.573194,1.921002 -1.562598,1.327923 -2.331149,4.004842 -2.331134,8.024838 l 0,6.537605 c -1.5e-5,2.710357 -0.456344,4.708001 -1.460845,5.763007 -0.985927,1.036861 -2.157584,1.549216 -4.817681,1.549196 l -1.7095,0 0,3.965943 1.7095,0 c 2.641495,1.6e-5 3.81315,0.463195 4.817681,1.518211 1.004501,1.055044 1.46083,2.861382 1.460845,5.608091 l 0,2.556172 c -1.5e-5,4.020026 0.768536,10.660189 2.331134,12.006269 1.550346,1.319827 5.070839,2.077935 9.573194,2.106906 l 0,-3.965941 c -2.581373,-0.01061 -5.752521,-0.464158 -6.54272,-1.254849 -0.799914,-0.800372 -1.19667,-6.451506 -1.196649,-9.016319 l 0,-2.788555 C 48.303668,69.915298 47.928575,67.94064 47.091497,66.649126 46.254384,65.357638 45.51975,64.49115 43.454931,64 c 2.046218,-0.454739 2.768369,-1.342112 3.605484,-2.633634 0.855681,-1.291479 1.243253,-3.464838 1.243274,-6.32072 l 0,-6.769983 c -2.1e-5,-2.564784 0.396735,-4.249978 1.196649,-5.050381 0.790199,-0.790653 3.961347,-1.030684 6.54272,-1.037961 l 0,-3.965941 z m 15.913882,0 0,3.965941 c 2.581375,0.0072 5.752523,0.247308 6.542722,1.037961 0.799912,0.800403 1.19667,2.485597 1.196648,5.050381 l 0,6.769983 c 2.2e-5,2.855882 0.387593,5.029241 1.243273,6.32072 0.837117,1.291522 1.55927,2.178895 3.605488,2.633634 -2.064821,0.49115 -2.799455,1.357638 -3.636568,2.649126 -0.837078,1.291514 -1.212171,3.266172 -1.212193,6.10383 l 0,2.788555 c 2.2e-5,2.564813 -0.396736,8.215947 -1.196648,9.016319 -0.790199,0.790691 -3.961347,1.244092 -6.542722,1.254849 l 0,3.965941 c 4.502355,-0.02897 8.02285,-0.787079 9.573197,-2.106906 1.562597,-1.34608 2.33115,-7.986243 2.331135,-12.006269 l 0,-2.556172 c 1.5e-5,-2.746709 0.456342,-4.553047 1.460846,-5.608091 1.004528,-1.055016 2.176183,-1.518195 4.817678,-1.518211 l 1.7095,0 0,-3.965943 -1.7095,0 c -2.660094,2e-5 -3.831749,-0.512335 -4.817678,-1.549196 -1.004504,-1.055006 -1.460831,-3.05265 -1.460846,-5.763007 l 0,-6.537605 c 1.5e-5,-4.019996 -0.768538,-6.696915 -2.331135,-8.024838 C 79.97979,38.822583 76.459295,38.243453 71.95694,38.22138 z"
id="path3006"
sodipodi:nodetypes="csccsccccscccccsccsccccsccccsccccsccscccccsccccsccsc" />
<path
style="fill:url(#linearGradient5378);fill-opacity:1;stroke:none"
d="m 107.87589,25.774638 c 0.72539,1.084602 1.12497,2.38464 1.12497,3.791498 l 0,20.986745 c -13.590951,7.970031 -40.28007,13.190143 -65.841216,13.190143 -7.038772,0 -13.841689,-0.408385 -20.303062,-1.148132 l 0,0.320409 c 6.539821,0.759061 13.436264,1.17483 20.570914,1.17483 25.561145,0 52.250262,-5.22011 65.841214,-13.19014 l 0,-20.986745 c 0,-1.559831 -0.517,-2.990759 -1.39282,-4.138608 z"
id="path5369"
sodipodi:nodetypes="cccsccsccc" />
<path
id="path5380"
d="m 25.485068,109.37056 c -3.798763,0 -6.856972,-3.04858 -6.856972,-6.83539 l 0,-33.002043 c 6.539821,-0.759061 13.436266,-1.174829 20.570912,-1.174829 25.561149,0 56.57875,-25.058477 70.169702,-17.088444 l 0,51.265316 c 0,3.78681 -3.05819,6.83539 -6.85697,6.83539 l -77.026672,0 z"
style="opacity:0.4;fill:url(#radialGradient5386);fill-opacity:1;stroke:none"
sodipodi:nodetypes="cccscccc" />
<path
sodipodi:nodetypes="ccccc"
id="path5414"
d="m 108,8 -4,8 c 3.30365,-0.176594 7.9579,2.481149 8,8 l 8,-4 C 120.007,14.388483 115.55603,8.131068 108,8 z"
style="fill:url(#radialGradient5426);fill-opacity:1;stroke:none;filter:url(#filter5416)"
clip-path="url(#clipPath5420)"
transform="matrix(0.85712141,0,0,0.85442216,9.142639,9.25759)" />
<path
clip-path="url(#clipPath5420)"
style="fill:url(#radialGradient5430);fill-opacity:1;stroke:none;filter:url(#filter5416)"
d="m 108,8 -4,8 c 3.30365,-0.176594 7.9579,2.481149 8,8 l 8,-4 C 120.007,14.388483 115.55603,8.131068 108,8 z"
id="path5428"
sodipodi:nodetypes="ccccc"
transform="matrix(-0.85712141,0,0,0.85442216,118.85417,9.25759)" />
<path
clip-path="url(#clipPath5420)"
style="opacity:0.52558139;fill:url(#radialGradient5436);fill-opacity:1;stroke:none;filter:url(#filter5416)"
d="m 108,8 -4,8 c 3.30365,-0.176594 7.9579,2.481149 8,8 l 8,-4 C 120.007,14.388483 115.55603,8.131068 108,8 z"
id="path5432"
sodipodi:nodetypes="ccccc"
transform="matrix(0.85712141,0,0,-0.85442216,9.142639,118.83578)" />
<path
transform="matrix(-0.85712141,0,0,-0.85442216,118.85417,118.83578)"
sodipodi:nodetypes="ccccc"
id="path5434"
d="m 108,8 -4,8 c 3.30365,-0.176594 7.9579,2.481149 8,8 l 8,-4 C 120.007,14.388483 115.55603,8.131068 108,8 z"
style="opacity:0.52558139;fill:url(#radialGradient5438);fill-opacity:1;stroke:none;filter:url(#filter5416)"
clip-path="url(#clipPath5420)" />
<path
clip-path="url(#clipPath5420)"
style="fill:url(#radialGradient5482);fill-opacity:1;stroke:none;filter:url(#filter5416)"
d="m 108,8 -4,8 c 3.30365,-0.176594 7.9579,2.481149 8,8 l 8,-4 C 120.007,14.388483 115.55603,8.131068 108,8 z"
id="path5455"
sodipodi:nodetypes="ccccc"
transform="matrix(0.85712141,0,0,0.85442216,9.142639,9.25759)" />
<path
transform="matrix(-0.85712141,0,0,0.85442216,118.85417,9.25759)"
sodipodi:nodetypes="ccccc"
id="path5457"
d="m 108,8 -4,8 c 3.30365,-0.176594 7.9579,2.481149 8,8 l 8,-4 C 120.007,14.388483 115.55603,8.131068 108,8 z"
style="fill:url(#radialGradient5480);fill-opacity:1;stroke:none;filter:url(#filter5416)"
clip-path="url(#clipPath5420)" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -10,6 +10,7 @@
<file>scalable/copy.svg</file>
<file>scalable/coremods.svg</file>
<file>scalable/custom-commands.svg</file>
<file>scalable/environment-variables.svg</file>
<file>scalable/externaltools.svg</file>
<file>scalable/help.svg</file>
<file>scalable/instance-settings.svg</file>

View File

@ -0,0 +1,345 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
id="svg2"
height="32"
width="32"
version="1.1"
sodipodi:docname="environment-variables.svg"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<sodipodi:namedview
pagecolor="#505050"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1011"
id="namedview52"
showgrid="false"
inkscape:zoom="7.375"
inkscape:cx="21.559322"
inkscape:cy="-2.9830509"
inkscape:window-x="0"
inkscape:window-y="32"
inkscape:window-maximized="1"
inkscape:current-layer="svg2"
inkscape:snap-bbox="true"
inkscape:bbox-paths="true"
inkscape:snap-bbox-edge-midpoints="true"
inkscape:snap-bbox-midpoints="true"
inkscape:bbox-nodes="true"
inkscape:pagecheckerboard="true"
inkscape:showpageshadow="2"
inkscape:deskcolor="#505050">
<inkscape:grid
type="xygrid"
id="grid858" />
</sodipodi:namedview>
<defs
id="defs4">
<linearGradient
id="linearGradient3931">
<stop
offset="0"
style="stop-color:#ffffff;stop-opacity:0"
id="stop3933" />
<stop
offset="0.69999987"
style="stop-color:#ffffff;stop-opacity:0.10396039"
id="stop3939" />
<stop
offset="1"
style="stop-color:#ffffff;stop-opacity:0.14356436"
id="stop3935" />
</linearGradient>
<linearGradient
id="linearGradient3900">
<stop
offset="0"
style="stop-color:#f6f6f6;stop-opacity:1"
id="stop3902" />
<stop
offset="0.75714284"
style="stop-color:#494949;stop-opacity:1"
id="stop3904" />
<stop
offset="1"
style="stop-color:#2c2c2c;stop-opacity:1"
id="stop3906" />
</linearGradient>
<linearGradient
id="linearGradient3808">
<stop
offset="0"
style="stop-color:#333333;stop-opacity:1"
id="stop3810" />
<stop
offset="1"
style="stop-color:#c8c8c8;stop-opacity:1"
id="stop3812" />
</linearGradient>
<linearGradient
id="linearGradient3030">
<stop
offset="0"
style="stop-color:#000000;stop-opacity:1"
id="stop3032" />
<stop
offset="0.75714284"
style="stop-color:#333333;stop-opacity:1"
id="stop3038" />
<stop
offset="1"
style="stop-color:#4d4d4d;stop-opacity:1"
id="stop3034" />
</linearGradient>
<radialGradient
gradientTransform="matrix(0.67596238,0.94191445,-0.76796117,0.55112488,7.7178628,-19.890271)"
gradientUnits="userSpaceOnUse"
xlink:href="#linearGradient3030"
id="radialGradient3036"
fy="14.242621"
fx="29.381905"
r="16.375"
cy="14.242621"
cx="29.381905" />
<linearGradient
gradientTransform="matrix(1.5,0,0,1,-16,4)"
gradientUnits="userSpaceOnUse"
xlink:href="#linearGradient3808"
id="linearGradient3824"
y2="1033.8622"
x2="34"
y1="1033.8622"
x1="30" />
<linearGradient
gradientTransform="matrix(0.82142857,0,0,1.500001,6.7142857,-522.68214)"
gradientUnits="userSpaceOnUse"
xlink:href="#linearGradient3808"
id="linearGradient3834"
y2="1039.3622"
x2="32"
y1="1043.3622"
x1="32" />
<radialGradient
gradientTransform="matrix(6.479993,1.9525666,-10.415476,2.1794781,10657.845,-1282.8793)"
gradientUnits="userSpaceOnUse"
xlink:href="#linearGradient3900"
id="radialGradient3844"
fy="1039.813"
fx="30.724609"
r="3"
cy="1039.813"
cx="30.724609" />
<radialGradient
gradientTransform="matrix(2.5191507,2.9862959,-4.0491019,3.333339,4186.8847,-2518.44)"
gradientUnits="userSpaceOnUse"
xlink:href="#linearGradient3900"
id="radialGradient3852"
fy="1039.813"
fx="30.724609"
r="3"
cy="1039.813"
cx="30.724609" />
<radialGradient
gradientTransform="matrix(-2.5191507,2.9863064,4.0491022,3.3333507,-4122.8849,-2518.4524)"
gradientUnits="userSpaceOnUse"
xlink:href="#linearGradient3900"
id="radialGradient3857"
fy="1039.813"
fx="30.724609"
r="3"
cy="1039.813"
cx="30.724609" />
<radialGradient
gradientTransform="matrix(-0.69414478,2.3073251,-1.6952184,-0.67174747,96.941544,960.82172)"
gradientUnits="userSpaceOnUse"
xlink:href="#linearGradient3900"
id="radialGradient3937"
fy="21.976955"
fx="31.946348"
r="19.25"
cy="21.976955"
cx="31.946348" />
</defs>
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<path
fill-rule="evenodd"
clip-rule="evenodd"
fill="#3366cc"
d="M 26,32 H 6 C 2.7,32 0,29.3 0,26 V 6 C 0,2.7 2.7,0 6,0 h 20 c 3.3,0 6,2.7 6,6 v 20 c 0,3.3 -2.7,6 -6,6 z"
id="path2" />
<path
fill="#daeeff"
fill-rule="evenodd"
clip-rule="evenodd"
d="M 28,6 C 28,4.9 27.1,4 26,4 H 6 C 4.9,4 4,4.9 4,6 v 20 c 0,1.1 0.9,2 2,2 h 20 c 1.1,0 2,-0.9 2,-2 z"
id="path4" />
<g
style="fill:#008000"
id="g869"
transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
<g
style="fill:#008000"
id="g871"
transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
<g
style="fill:#008000"
id="g873"
transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
<g
style="fill:#008000"
id="g875"
transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
<g
style="fill:#008000"
id="g877"
transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
<g
style="fill:#008000"
id="g879"
transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
<g
style="fill:#008000"
id="g881"
transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
<g
style="fill:#008000"
id="g883"
transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
<g
style="fill:#008000"
id="g885"
transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
<g
style="fill:#008000"
id="g887"
transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
<g
style="fill:#008000"
id="g889"
transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
<g
style="fill:#008000"
id="g891"
transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
<g
style="fill:#008000"
id="g893"
transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
<g
style="fill:#008000"
id="g895"
transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
<g
style="fill:#008000"
id="g897"
transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
<g
id="g856"
style="fill:#c1272d;fill-opacity:1"
transform="matrix(0.0361121,0,0,0.0361121,6.5218379,6.0218363)">
<g
id="g854"
style="fill:#c1272d;fill-opacity:1">
<path
inkscape:connector-curvature="0"
id="path850"
d="m -14.4505,276.30781 c 0,-6.995 2.705,-13.403 7.846,-18.556 l 156.788,-156.782 c 5.128,-5.140997 11.554,-7.851997 18.568,-7.851997 7.026,0 13.452,2.717 18.556,7.845997 l 16.83,16.83 c 5.129,5.135 7.84,11.549 7.84,18.538 0,7.026 -2.717,13.452 -7.846,18.556 l -121.415001,121.42 121.427001,121.433 c 5.129,5.135 7.84,11.555 7.84,18.55 0,7.02 -2.717,13.439 -7.846,18.544 l -16.775,16.774 c -5.116,5.165 -11.555,7.895 -18.611,7.895 -7.044,0 -13.47,-2.723 -18.556,-7.846 l -156.813,-156.8 c -5.128,-5.14 -7.833,-11.549 -7.833,-18.55 z"
style="fill:#c1272d;fill-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path322"
d="m 539.38069,276.30781 c 0,-6.995 -2.705,-13.403 -7.846,-18.556 l -156.788,-156.782 c -5.128,-5.140997 -11.554,-7.851997 -18.568,-7.851997 -7.026,0 -13.452,2.717 -18.556,7.845997 l -16.83,16.83 c -5.129,5.135 -7.84,11.549 -7.84,18.538 0,7.026 2.717,13.452 7.846,18.556 l 121.415,121.42 -121.427,121.433 c -5.129,5.135 -7.84,11.555 -7.84,18.55 0,7.02 2.717,13.439 7.846,18.544 l 16.775,16.774 c 5.116,5.165 11.555,7.895 18.611,7.895 7.044,0 13.47,-2.723 18.556,-7.846 l 156.813,-156.8 c 5.128,-5.14 7.833,-11.549 7.833,-18.55 z"
style="fill:#c1272d;fill-opacity:1" />
</g>
</g>
<g
id="g858"
style="fill:#00ff00"
transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
<g
id="g860"
style="fill:#00ff00"
transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
<g
id="g862"
style="fill:#00ff00"
transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
<g
id="g864"
style="fill:#00ff00"
transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
<g
id="g866"
style="fill:#00ff00"
transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
<g
id="g868"
style="fill:#00ff00"
transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
<g
id="g870"
style="fill:#00ff00"
transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
<g
id="g872"
style="fill:#00ff00"
transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
<g
id="g874"
style="fill:#00ff00"
transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
<g
id="g876"
style="fill:#00ff00"
transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
<g
id="g878"
style="fill:#00ff00"
transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
<g
id="g880"
style="fill:#00ff00"
transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
<g
id="g882"
style="fill:#00ff00"
transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
<g
id="g884"
style="fill:#00ff00"
transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
<g
id="g886"
style="fill:#00ff00"
transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
<g
id="g12">
<path
id="path6"
d="m 6,28 h 20 c 1.1,0 2,-0.9 2,-2 V 9 6 C 28,4.9 27.1,4 26,4 H 6 C 4.9,4 4,4.9 4,6 v 3 17 c 0,1.1 0.9,2 2,2 z"
fill="none" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -10,6 +10,7 @@
<file>scalable/copy.svg</file>
<file>scalable/coremods.svg</file>
<file>scalable/custom-commands.svg</file>
<file>scalable/environment-variables.svg</file>
<file>scalable/externaltools.svg</file>
<file>scalable/help.svg</file>
<file>scalable/instance-settings.svg</file>

View File

@ -0,0 +1,347 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
id="svg2"
height="32"
width="32"
version="1.1"
sodipodi:docname="environment-variables.svg"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<sodipodi:namedview
pagecolor="#505050"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1011"
id="namedview52"
showgrid="false"
inkscape:zoom="10.429825"
inkscape:cx="3.4995793"
inkscape:cy="11.793103"
inkscape:window-x="0"
inkscape:window-y="32"
inkscape:window-maximized="1"
inkscape:current-layer="svg2"
inkscape:snap-bbox="true"
inkscape:bbox-paths="true"
inkscape:snap-bbox-edge-midpoints="true"
inkscape:snap-bbox-midpoints="true"
inkscape:bbox-nodes="true"
inkscape:pagecheckerboard="true"
inkscape:showpageshadow="2"
inkscape:deskcolor="#505050">
<inkscape:grid
type="xygrid"
id="grid858" />
</sodipodi:namedview>
<defs
id="defs4">
<linearGradient
id="linearGradient3931">
<stop
offset="0"
style="stop-color:#ffffff;stop-opacity:0"
id="stop3933" />
<stop
offset="0.69999987"
style="stop-color:#ffffff;stop-opacity:0.10396039"
id="stop3939" />
<stop
offset="1"
style="stop-color:#ffffff;stop-opacity:0.14356436"
id="stop3935" />
</linearGradient>
<linearGradient
id="linearGradient3900">
<stop
offset="0"
style="stop-color:#f6f6f6;stop-opacity:1"
id="stop3902" />
<stop
offset="0.75714284"
style="stop-color:#494949;stop-opacity:1"
id="stop3904" />
<stop
offset="1"
style="stop-color:#2c2c2c;stop-opacity:1"
id="stop3906" />
</linearGradient>
<linearGradient
id="linearGradient3808">
<stop
offset="0"
style="stop-color:#333333;stop-opacity:1"
id="stop3810" />
<stop
offset="1"
style="stop-color:#c8c8c8;stop-opacity:1"
id="stop3812" />
</linearGradient>
<linearGradient
id="linearGradient3030">
<stop
offset="0"
style="stop-color:#000000;stop-opacity:1"
id="stop3032" />
<stop
offset="0.75714284"
style="stop-color:#333333;stop-opacity:1"
id="stop3038" />
<stop
offset="1"
style="stop-color:#4d4d4d;stop-opacity:1"
id="stop3034" />
</linearGradient>
<radialGradient
gradientTransform="matrix(0.67596238,0.94191445,-0.76796117,0.55112488,7.7178628,-19.890271)"
gradientUnits="userSpaceOnUse"
xlink:href="#linearGradient3030"
id="radialGradient3036"
fy="14.242621"
fx="29.381905"
r="16.375"
cy="14.242621"
cx="29.381905" />
<linearGradient
gradientTransform="matrix(1.5,0,0,1,-16,4)"
gradientUnits="userSpaceOnUse"
xlink:href="#linearGradient3808"
id="linearGradient3824"
y2="1033.8622"
x2="34"
y1="1033.8622"
x1="30" />
<linearGradient
gradientTransform="matrix(0.82142857,0,0,1.500001,6.7142857,-522.68214)"
gradientUnits="userSpaceOnUse"
xlink:href="#linearGradient3808"
id="linearGradient3834"
y2="1039.3622"
x2="32"
y1="1043.3622"
x1="32" />
<radialGradient
gradientTransform="matrix(6.479993,1.9525666,-10.415476,2.1794781,10657.845,-1282.8793)"
gradientUnits="userSpaceOnUse"
xlink:href="#linearGradient3900"
id="radialGradient3844"
fy="1039.813"
fx="30.724609"
r="3"
cy="1039.813"
cx="30.724609" />
<radialGradient
gradientTransform="matrix(2.5191507,2.9862959,-4.0491019,3.333339,4186.8847,-2518.44)"
gradientUnits="userSpaceOnUse"
xlink:href="#linearGradient3900"
id="radialGradient3852"
fy="1039.813"
fx="30.724609"
r="3"
cy="1039.813"
cx="30.724609" />
<radialGradient
gradientTransform="matrix(-2.5191507,2.9863064,4.0491022,3.3333507,-4122.8849,-2518.4524)"
gradientUnits="userSpaceOnUse"
xlink:href="#linearGradient3900"
id="radialGradient3857"
fy="1039.813"
fx="30.724609"
r="3"
cy="1039.813"
cx="30.724609" />
<radialGradient
gradientTransform="matrix(-0.69414478,2.3073251,-1.6952184,-0.67174747,96.941544,960.82172)"
gradientUnits="userSpaceOnUse"
xlink:href="#linearGradient3900"
id="radialGradient3937"
fy="21.976955"
fx="31.946348"
r="19.25"
cy="21.976955"
cx="31.946348" />
</defs>
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<path
id="path2"
d="M 28,6 C 28,4.9 27.1,4 26,4 H 6 C 4.9,4 4,4.9 4,6 v 20 c 0,1.1 0.9,2 2,2 h 20 c 1.1,0 2,-0.9 2,-2 z"
fill="#f2f2f2"
clip-rule="evenodd"
fill-rule="evenodd" />
<g
style="fill:#008000"
id="g869"
transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
<g
style="fill:#008000"
id="g871"
transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
<g
style="fill:#008000"
id="g873"
transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
<g
style="fill:#008000"
id="g875"
transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
<g
style="fill:#008000"
id="g877"
transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
<g
style="fill:#008000"
id="g879"
transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
<g
style="fill:#008000"
id="g881"
transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
<g
style="fill:#008000"
id="g883"
transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
<g
style="fill:#008000"
id="g885"
transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
<g
style="fill:#008000"
id="g887"
transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
<g
style="fill:#008000"
id="g889"
transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
<g
style="fill:#008000"
id="g891"
transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
<g
style="fill:#008000"
id="g893"
transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
<g
style="fill:#008000"
id="g895"
transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
<g
style="fill:#008000"
id="g897"
transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
<g
id="g856"
style="fill:#c1272d;fill-opacity:1"
transform="matrix(0.0361121,0,0,0.0361121,6.5218379,6.0218363)">
<g
id="g854"
style="fill:#c1272d;fill-opacity:1">
<path
inkscape:connector-curvature="0"
id="path850"
d="m -14.4505,276.30781 c 0,-6.995 2.705,-13.403 7.846,-18.556 l 156.788,-156.782 c 5.128,-5.140997 11.554,-7.851997 18.568,-7.851997 7.026,0 13.452,2.717 18.556,7.845997 l 16.83,16.83 c 5.129,5.135 7.84,11.549 7.84,18.538 0,7.026 -2.717,13.452 -7.846,18.556 l -121.415001,121.42 121.427001,121.433 c 5.129,5.135 7.84,11.555 7.84,18.55 0,7.02 -2.717,13.439 -7.846,18.544 l -16.775,16.774 c -5.116,5.165 -11.555,7.895 -18.611,7.895 -7.044,0 -13.47,-2.723 -18.556,-7.846 l -156.813,-156.8 c -5.128,-5.14 -7.833,-11.549 -7.833,-18.55 z"
style="fill:#c1272d;fill-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path322"
d="m 539.38069,276.30781 c 0,-6.995 -2.705,-13.403 -7.846,-18.556 l -156.788,-156.782 c -5.128,-5.140997 -11.554,-7.851997 -18.568,-7.851997 -7.026,0 -13.452,2.717 -18.556,7.845997 l -16.83,16.83 c -5.129,5.135 -7.84,11.549 -7.84,18.538 0,7.026 2.717,13.452 7.846,18.556 l 121.415,121.42 -121.427,121.433 c -5.129,5.135 -7.84,11.555 -7.84,18.55 0,7.02 2.717,13.439 7.846,18.544 l 16.775,16.774 c 5.116,5.165 11.555,7.895 18.611,7.895 7.044,0 13.47,-2.723 18.556,-7.846 l 156.813,-156.8 c 5.128,-5.14 7.833,-11.549 7.833,-18.55 z"
style="fill:#c1272d;fill-opacity:1" />
</g>
</g>
<g
id="g858"
style="fill:#00ff00"
transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
<g
id="g860"
style="fill:#00ff00"
transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
<g
id="g862"
style="fill:#00ff00"
transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
<g
id="g864"
style="fill:#00ff00"
transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
<g
id="g866"
style="fill:#00ff00"
transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
<g
id="g868"
style="fill:#00ff00"
transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
<g
id="g870"
style="fill:#00ff00"
transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
<g
id="g872"
style="fill:#00ff00"
transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
<g
id="g874"
style="fill:#00ff00"
transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
<g
id="g876"
style="fill:#00ff00"
transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
<g
id="g878"
style="fill:#00ff00"
transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
<g
id="g880"
style="fill:#00ff00"
transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
<g
id="g882"
style="fill:#00ff00"
transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
<g
id="g884"
style="fill:#00ff00"
transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
<g
id="g886"
style="fill:#00ff00"
transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
<g
id="g12">
<path
id="path6"
d="m 6,28 h 20 c 1.1,0 2,-0.9 2,-2 V 9 6 C 28,4.9 27.1,4 26,4 H 6 C 4.9,4 4,4.9 4,6 v 3 17 c 0,1.1 0.9,2 2,2 z"
fill="none" />
<path
id="path8"
d="M 26,0 H 6 C 2.7,0 0,2.7 0,6 V 9 H 4 V 6 C 4,4.9 4.9,4 6,4 h 20 c 1.1,0 2,0.9 2,2 v 3 h 4 V 6 C 32,2.7 29.3,0 26,0 Z"
fill="#39b54a" />
<path
id="path10"
d="m 28,26 c 0,1.1 -0.9,2 -2,2 H 6 C 4.9,28 4,27.1 4,26 V 9 H 0 v 17 c 0,3.3 2.7,6 6,6 h 20 c 3.3,0 6,-2.7 6,-6 V 9 h -4 z"
fill="#8c6239" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -10,6 +10,7 @@
<file>scalable/copy.svg</file>
<file>scalable/coremods.svg</file>
<file>scalable/custom-commands.svg</file>
<file>scalable/environment-variables.svg</file>
<file>scalable/externaltools.svg</file>
<file>scalable/help.svg</file>
<file>scalable/instance-settings.svg</file>

View File

@ -0,0 +1,345 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
id="svg2"
height="32"
width="32"
version="1.1"
sodipodi:docname="environment-variables.svg"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<sodipodi:namedview
pagecolor="#505050"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1720"
inkscape:window-height="749"
id="namedview52"
showgrid="false"
inkscape:zoom="14.75"
inkscape:cx="20.305085"
inkscape:cy="19.79661"
inkscape:window-x="153"
inkscape:window-y="287"
inkscape:window-maximized="0"
inkscape:current-layer="svg2"
inkscape:snap-bbox="true"
inkscape:bbox-paths="true"
inkscape:snap-bbox-edge-midpoints="true"
inkscape:snap-bbox-midpoints="true"
inkscape:bbox-nodes="true"
inkscape:pagecheckerboard="true"
inkscape:showpageshadow="2"
inkscape:deskcolor="#505050">
<inkscape:grid
type="xygrid"
id="grid858" />
</sodipodi:namedview>
<defs
id="defs4">
<linearGradient
id="linearGradient3931">
<stop
offset="0"
style="stop-color:#ffffff;stop-opacity:0"
id="stop3933" />
<stop
offset="0.69999987"
style="stop-color:#ffffff;stop-opacity:0.10396039"
id="stop3939" />
<stop
offset="1"
style="stop-color:#ffffff;stop-opacity:0.14356436"
id="stop3935" />
</linearGradient>
<linearGradient
id="linearGradient3900">
<stop
offset="0"
style="stop-color:#f6f6f6;stop-opacity:1"
id="stop3902" />
<stop
offset="0.75714284"
style="stop-color:#494949;stop-opacity:1"
id="stop3904" />
<stop
offset="1"
style="stop-color:#2c2c2c;stop-opacity:1"
id="stop3906" />
</linearGradient>
<linearGradient
id="linearGradient3808">
<stop
offset="0"
style="stop-color:#333333;stop-opacity:1"
id="stop3810" />
<stop
offset="1"
style="stop-color:#c8c8c8;stop-opacity:1"
id="stop3812" />
</linearGradient>
<linearGradient
id="linearGradient3030">
<stop
offset="0"
style="stop-color:#000000;stop-opacity:1"
id="stop3032" />
<stop
offset="0.75714284"
style="stop-color:#333333;stop-opacity:1"
id="stop3038" />
<stop
offset="1"
style="stop-color:#4d4d4d;stop-opacity:1"
id="stop3034" />
</linearGradient>
<radialGradient
gradientTransform="matrix(0.67596238,0.94191445,-0.76796117,0.55112488,7.7178628,-19.890271)"
gradientUnits="userSpaceOnUse"
xlink:href="#linearGradient3030"
id="radialGradient3036"
fy="14.242621"
fx="29.381905"
r="16.375"
cy="14.242621"
cx="29.381905" />
<linearGradient
gradientTransform="matrix(1.5,0,0,1,-16,4)"
gradientUnits="userSpaceOnUse"
xlink:href="#linearGradient3808"
id="linearGradient3824"
y2="1033.8622"
x2="34"
y1="1033.8622"
x1="30" />
<linearGradient
gradientTransform="matrix(0.82142857,0,0,1.500001,6.7142857,-522.68214)"
gradientUnits="userSpaceOnUse"
xlink:href="#linearGradient3808"
id="linearGradient3834"
y2="1039.3622"
x2="32"
y1="1043.3622"
x1="32" />
<radialGradient
gradientTransform="matrix(6.479993,1.9525666,-10.415476,2.1794781,10657.845,-1282.8793)"
gradientUnits="userSpaceOnUse"
xlink:href="#linearGradient3900"
id="radialGradient3844"
fy="1039.813"
fx="30.724609"
r="3"
cy="1039.813"
cx="30.724609" />
<radialGradient
gradientTransform="matrix(2.5191507,2.9862959,-4.0491019,3.333339,4186.8847,-2518.44)"
gradientUnits="userSpaceOnUse"
xlink:href="#linearGradient3900"
id="radialGradient3852"
fy="1039.813"
fx="30.724609"
r="3"
cy="1039.813"
cx="30.724609" />
<radialGradient
gradientTransform="matrix(-2.5191507,2.9863064,4.0491022,3.3333507,-4122.8849,-2518.4524)"
gradientUnits="userSpaceOnUse"
xlink:href="#linearGradient3900"
id="radialGradient3857"
fy="1039.813"
fx="30.724609"
r="3"
cy="1039.813"
cx="30.724609" />
<radialGradient
gradientTransform="matrix(-0.69414478,2.3073251,-1.6952184,-0.67174747,96.941544,960.82172)"
gradientUnits="userSpaceOnUse"
xlink:href="#linearGradient3900"
id="radialGradient3937"
fy="21.976955"
fx="31.946348"
r="19.25"
cy="21.976955"
cx="31.946348" />
</defs>
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M 26,32 H 6 C 2.7,32 0,29.3 0,26 V 6 C 0,2.7 2.7,0 6,0 h 20 c 3.3,0 6,2.7 6,6 v 20 c 0,3.3 -2.7,6 -6,6 z"
id="path2"
style="fill-opacity:1;fill:#010101" />
<path
fill-rule="evenodd"
clip-rule="evenodd"
fill="#f2f2f2"
d="M 28,6 C 28,4.9 27.1,4 26,4 H 6 C 4.9,4 4,4.9 4,6 v 20 c 0,1.1 0.9,2 2,2 h 20 c 1.1,0 2,-0.9 2,-2 z"
id="path4" />
<g
style="fill:#008000"
id="g869"
transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
<g
style="fill:#008000"
id="g871"
transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
<g
style="fill:#008000"
id="g873"
transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
<g
style="fill:#008000"
id="g875"
transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
<g
style="fill:#008000"
id="g877"
transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
<g
style="fill:#008000"
id="g879"
transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
<g
style="fill:#008000"
id="g881"
transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
<g
style="fill:#008000"
id="g883"
transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
<g
style="fill:#008000"
id="g885"
transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
<g
style="fill:#008000"
id="g887"
transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
<g
style="fill:#008000"
id="g889"
transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
<g
style="fill:#008000"
id="g891"
transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
<g
style="fill:#008000"
id="g893"
transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
<g
style="fill:#008000"
id="g895"
transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
<g
style="fill:#008000"
id="g897"
transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
<g
id="g856"
style="fill:#666666;fill-opacity:1"
transform="matrix(0.0361121,0,0,0.0361121,6.5218379,6.0218363)">
<g
id="g854"
style="fill:#666666;fill-opacity:1">
<path
inkscape:connector-curvature="0"
id="path850"
d="m -14.4505,276.30781 c 0,-6.995 2.705,-13.403 7.846,-18.556 l 156.788,-156.782 c 5.128,-5.140997 11.554,-7.851997 18.568,-7.851997 7.026,0 13.452,2.717 18.556,7.845997 l 16.83,16.83 c 5.129,5.135 7.84,11.549 7.84,18.538 0,7.026 -2.717,13.452 -7.846,18.556 l -121.415001,121.42 121.427001,121.433 c 5.129,5.135 7.84,11.555 7.84,18.55 0,7.02 -2.717,13.439 -7.846,18.544 l -16.775,16.774 c -5.116,5.165 -11.555,7.895 -18.611,7.895 -7.044,0 -13.47,-2.723 -18.556,-7.846 l -156.813,-156.8 c -5.128,-5.14 -7.833,-11.549 -7.833,-18.55 z"
style="fill:#666666;fill-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path322"
d="m 539.38069,276.30781 c 0,-6.995 -2.705,-13.403 -7.846,-18.556 l -156.788,-156.782 c -5.128,-5.140997 -11.554,-7.851997 -18.568,-7.851997 -7.026,0 -13.452,2.717 -18.556,7.845997 l -16.83,16.83 c -5.129,5.135 -7.84,11.549 -7.84,18.538 0,7.026 2.717,13.452 7.846,18.556 l 121.415,121.42 -121.427,121.433 c -5.129,5.135 -7.84,11.555 -7.84,18.55 0,7.02 2.717,13.439 7.846,18.544 l 16.775,16.774 c 5.116,5.165 11.555,7.895 18.611,7.895 7.044,0 13.47,-2.723 18.556,-7.846 l 156.813,-156.8 c 5.128,-5.14 7.833,-11.549 7.833,-18.55 z"
style="fill:#666666;fill-opacity:1" />
</g>
</g>
<g
id="g858"
style="fill:#00ff00"
transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
<g
id="g860"
style="fill:#00ff00"
transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
<g
id="g862"
style="fill:#00ff00"
transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
<g
id="g864"
style="fill:#00ff00"
transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
<g
id="g866"
style="fill:#00ff00"
transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
<g
id="g868"
style="fill:#00ff00"
transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
<g
id="g870"
style="fill:#00ff00"
transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
<g
id="g872"
style="fill:#00ff00"
transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
<g
id="g874"
style="fill:#00ff00"
transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
<g
id="g876"
style="fill:#00ff00"
transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
<g
id="g878"
style="fill:#00ff00"
transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
<g
id="g880"
style="fill:#00ff00"
transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
<g
id="g882"
style="fill:#00ff00"
transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
<g
id="g884"
style="fill:#00ff00"
transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
<g
id="g886"
style="fill:#00ff00"
transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
<g
id="g12">
<path
id="path6"
d="m 6,28 h 20 c 1.1,0 2,-0.9 2,-2 V 9 6 C 28,4.9 27.1,4 26,4 H 6 C 4.9,4 4,4.9 4,6 v 3 17 c 0,1.1 0.9,2 2,2 z"
fill="none" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -10,6 +10,7 @@
<file>scalable/copy.svg</file>
<file>scalable/coremods.svg</file>
<file>scalable/custom-commands.svg</file>
<file>scalable/environment-variables.svg</file>
<file>scalable/externaltools.svg</file>
<file>scalable/help.svg</file>
<file>scalable/instance-settings.svg</file>

View File

@ -0,0 +1,345 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
id="svg2"
height="32"
width="32"
version="1.1"
sodipodi:docname="environment-variables.svg"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<sodipodi:namedview
pagecolor="#505050"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1011"
id="namedview52"
showgrid="false"
inkscape:zoom="11.313709"
inkscape:cx="5.5242717"
inkscape:cy="12.28598"
inkscape:window-x="0"
inkscape:window-y="32"
inkscape:window-maximized="1"
inkscape:current-layer="svg2"
inkscape:snap-bbox="true"
inkscape:bbox-paths="true"
inkscape:snap-bbox-edge-midpoints="true"
inkscape:snap-bbox-midpoints="true"
inkscape:bbox-nodes="true"
inkscape:pagecheckerboard="true"
inkscape:showpageshadow="2"
inkscape:deskcolor="#505050">
<inkscape:grid
type="xygrid"
id="grid858" />
</sodipodi:namedview>
<defs
id="defs4">
<linearGradient
id="linearGradient3931">
<stop
offset="0"
style="stop-color:#ffffff;stop-opacity:0"
id="stop3933" />
<stop
offset="0.69999987"
style="stop-color:#ffffff;stop-opacity:0.10396039"
id="stop3939" />
<stop
offset="1"
style="stop-color:#ffffff;stop-opacity:0.14356436"
id="stop3935" />
</linearGradient>
<linearGradient
id="linearGradient3900">
<stop
offset="0"
style="stop-color:#f6f6f6;stop-opacity:1"
id="stop3902" />
<stop
offset="0.75714284"
style="stop-color:#494949;stop-opacity:1"
id="stop3904" />
<stop
offset="1"
style="stop-color:#2c2c2c;stop-opacity:1"
id="stop3906" />
</linearGradient>
<linearGradient
id="linearGradient3808">
<stop
offset="0"
style="stop-color:#333333;stop-opacity:1"
id="stop3810" />
<stop
offset="1"
style="stop-color:#c8c8c8;stop-opacity:1"
id="stop3812" />
</linearGradient>
<linearGradient
id="linearGradient3030">
<stop
offset="0"
style="stop-color:#000000;stop-opacity:1"
id="stop3032" />
<stop
offset="0.75714284"
style="stop-color:#333333;stop-opacity:1"
id="stop3038" />
<stop
offset="1"
style="stop-color:#4d4d4d;stop-opacity:1"
id="stop3034" />
</linearGradient>
<radialGradient
gradientTransform="matrix(0.67596238,0.94191445,-0.76796117,0.55112488,7.7178628,-19.890271)"
gradientUnits="userSpaceOnUse"
xlink:href="#linearGradient3030"
id="radialGradient3036"
fy="14.242621"
fx="29.381905"
r="16.375"
cy="14.242621"
cx="29.381905" />
<linearGradient
gradientTransform="matrix(1.5,0,0,1,-16,4)"
gradientUnits="userSpaceOnUse"
xlink:href="#linearGradient3808"
id="linearGradient3824"
y2="1033.8622"
x2="34"
y1="1033.8622"
x1="30" />
<linearGradient
gradientTransform="matrix(0.82142857,0,0,1.500001,6.7142857,-522.68214)"
gradientUnits="userSpaceOnUse"
xlink:href="#linearGradient3808"
id="linearGradient3834"
y2="1039.3622"
x2="32"
y1="1043.3622"
x1="32" />
<radialGradient
gradientTransform="matrix(6.479993,1.9525666,-10.415476,2.1794781,10657.845,-1282.8793)"
gradientUnits="userSpaceOnUse"
xlink:href="#linearGradient3900"
id="radialGradient3844"
fy="1039.813"
fx="30.724609"
r="3"
cy="1039.813"
cx="30.724609" />
<radialGradient
gradientTransform="matrix(2.5191507,2.9862959,-4.0491019,3.333339,4186.8847,-2518.44)"
gradientUnits="userSpaceOnUse"
xlink:href="#linearGradient3900"
id="radialGradient3852"
fy="1039.813"
fx="30.724609"
r="3"
cy="1039.813"
cx="30.724609" />
<radialGradient
gradientTransform="matrix(-2.5191507,2.9863064,4.0491022,3.3333507,-4122.8849,-2518.4524)"
gradientUnits="userSpaceOnUse"
xlink:href="#linearGradient3900"
id="radialGradient3857"
fy="1039.813"
fx="30.724609"
r="3"
cy="1039.813"
cx="30.724609" />
<radialGradient
gradientTransform="matrix(-0.69414478,2.3073251,-1.6952184,-0.67174747,96.941544,960.82172)"
gradientUnits="userSpaceOnUse"
xlink:href="#linearGradient3900"
id="radialGradient3937"
fy="21.976955"
fx="31.946348"
r="19.25"
cy="21.976955"
cx="31.946348" />
</defs>
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M 26,32 H 6 C 2.7,32 0,29.3 0,26 V 6 C 0,2.7 2.7,0 6,0 h 20 c 3.3,0 6,2.7 6,6 v 20 c 0,3.3 -2.7,6 -6,6 z"
id="path2"
style="fill-opacity:1;fill:#f2f2f2" />
<g
style="fill:#008000"
id="g869"
transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
<g
style="fill:#008000"
id="g871"
transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
<g
style="fill:#008000"
id="g873"
transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
<g
style="fill:#008000"
id="g875"
transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
<g
style="fill:#008000"
id="g877"
transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
<g
style="fill:#008000"
id="g879"
transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
<g
style="fill:#008000"
id="g881"
transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
<g
style="fill:#008000"
id="g883"
transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
<g
style="fill:#008000"
id="g885"
transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
<g
style="fill:#008000"
id="g887"
transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
<g
style="fill:#008000"
id="g889"
transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
<g
style="fill:#008000"
id="g891"
transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
<g
style="fill:#008000"
id="g893"
transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
<g
style="fill:#008000"
id="g895"
transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
<g
style="fill:#008000"
id="g897"
transform="matrix(0.04286288,0,0,0.04286288,4.7499946,5.2499965)" />
<path
id="path2-3"
d="M 28,6 C 28,4.9 27.1,4 26,4 H 6 C 4.9,4 4,4.9 4,6 v 20.000001 c 0,1.1 0.9,2 2,2 h 20 c 1.1,0 2,-0.9 2,-2 z"
fill="#4d4d4d"
clip-rule="evenodd"
fill-rule="evenodd" />
<g
id="g856"
style="fill:#ffffff;fill-opacity:1"
transform="matrix(0.0361121,0,0,0.0361121,6.5218379,6.0218363)">
<g
id="g854"
style="fill:#ffffff;fill-opacity:1">
<path
inkscape:connector-curvature="0"
id="path850"
d="m -14.4505,276.30781 c 0,-6.995 2.705,-13.403 7.846,-18.556 l 156.788,-156.782 c 5.128,-5.140997 11.554,-7.851997 18.568,-7.851997 7.026,0 13.452,2.717 18.556,7.845997 l 16.83,16.83 c 5.129,5.135 7.84,11.549 7.84,18.538 0,7.026 -2.717,13.452 -7.846,18.556 l -121.415001,121.42 121.427001,121.433 c 5.129,5.135 7.84,11.555 7.84,18.55 0,7.02 -2.717,13.439 -7.846,18.544 l -16.775,16.774 c -5.116,5.165 -11.555,7.895 -18.611,7.895 -7.044,0 -13.47,-2.723 -18.556,-7.846 l -156.813,-156.8 c -5.128,-5.14 -7.833,-11.549 -7.833,-18.55 z"
style="fill:#ffffff;fill-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path322"
d="m 539.38069,276.30781 c 0,-6.995 -2.705,-13.403 -7.846,-18.556 l -156.788,-156.782 c -5.128,-5.140997 -11.554,-7.851997 -18.568,-7.851997 -7.026,0 -13.452,2.717 -18.556,7.845997 l -16.83,16.83 c -5.129,5.135 -7.84,11.549 -7.84,18.538 0,7.026 2.717,13.452 7.846,18.556 l 121.415,121.42 -121.427,121.433 c -5.129,5.135 -7.84,11.555 -7.84,18.55 0,7.02 2.717,13.439 7.846,18.544 l 16.775,16.774 c 5.116,5.165 11.555,7.895 18.611,7.895 7.044,0 13.47,-2.723 18.556,-7.846 l 156.813,-156.8 c 5.128,-5.14 7.833,-11.549 7.833,-18.55 z"
style="fill:#ffffff;fill-opacity:1" />
</g>
</g>
<g
id="g858"
style="fill:#00ff00"
transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
<g
id="g860"
style="fill:#00ff00"
transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
<g
id="g862"
style="fill:#00ff00"
transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
<g
id="g864"
style="fill:#00ff00"
transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
<g
id="g866"
style="fill:#00ff00"
transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
<g
id="g868"
style="fill:#00ff00"
transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
<g
id="g870"
style="fill:#00ff00"
transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
<g
id="g872"
style="fill:#00ff00"
transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
<g
id="g874"
style="fill:#00ff00"
transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
<g
id="g876"
style="fill:#00ff00"
transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
<g
id="g878"
style="fill:#00ff00"
transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
<g
id="g880"
style="fill:#00ff00"
transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
<g
id="g882"
style="fill:#00ff00"
transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
<g
id="g884"
style="fill:#00ff00"
transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
<g
id="g886"
style="fill:#00ff00"
transform="matrix(0.04286288,0,0,0.04286288,4.7499948,4.2499932)" />
<g
id="g12">
<path
id="path6"
d="m 6,28 h 20 c 1.1,0 2,-0.9 2,-2 V 9 6 C 28,4.9 27.1,4 26,4 H 6 C 4.9,4 4,4.9 4,6 v 3 17 c 0,1.1 0.9,2 2,2 z"
fill="none" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -39,87 +39,76 @@
#include <QDebug>
#include <QJsonDocument>
#include <QJsonObject>
#include <QList>
#include <QNetworkRequest>
#include <QStringList>
#include <QUrl>
#include <memory>
#include "Application.h"
#include "BuildConfig.h"
#include "net/StaticHeaderProxy.h"
ImgurAlbumCreation::ImgurAlbumCreation(QList<ScreenShot::Ptr> screenshots) : NetAction(), m_screenshots(screenshots)
Net::NetRequest::Ptr ImgurAlbumCreation::make(std::shared_ptr<ImgurAlbumCreation::Result> output, QList<ScreenShot::Ptr> screenshots)
{
m_url = BuildConfig.IMGUR_BASE_URL + "album.json";
m_state = State::Inactive;
auto up = makeShared<ImgurAlbumCreation>();
up->m_url = BuildConfig.IMGUR_BASE_URL + "album.json";
up->m_sink.reset(new Sink(output));
up->m_screenshots = screenshots;
return up;
}
void ImgurAlbumCreation::executeTask()
QNetworkReply* ImgurAlbumCreation::getReply(QNetworkRequest& request)
{
m_state = State::Running;
QNetworkRequest request(m_url);
request.setHeader(QNetworkRequest::UserAgentHeader, APPLICATION->getUserAgentUncached().toUtf8());
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
request.setRawHeader("Authorization", QString("Client-ID %1").arg(BuildConfig.IMGUR_CLIENT_ID).toStdString().c_str());
request.setRawHeader("Accept", "application/json");
QStringList hashes;
for (auto shot : m_screenshots) {
hashes.append(shot->m_imgurDeleteHash);
}
const QByteArray data = "deletehashes=" + hashes.join(',').toUtf8() + "&title=Minecraft%20Screenshots&privacy=hidden";
return m_network->post(request, data);
};
QNetworkReply* rep = APPLICATION->network()->post(request, data);
m_reply.reset(rep);
connect(rep, &QNetworkReply::uploadProgress, this, &ImgurAlbumCreation::downloadProgress);
connect(rep, &QNetworkReply::finished, this, &ImgurAlbumCreation::downloadFinished);
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) // QNetworkReply::errorOccurred added in 5.15
connect(rep, &QNetworkReply::errorOccurred, this, &ImgurAlbumCreation::downloadError);
#else
connect(rep, QOverload<QNetworkReply::NetworkError>::of(&QNetworkReply::error), this, &ImgurAlbumCreation::downloadError);
#endif
connect(rep, &QNetworkReply::sslErrors, this, &ImgurAlbumCreation::sslErrors);
void ImgurAlbumCreation::init()
{
qDebug() << "Setting up imgur upload";
auto api_headers = new Net::StaticHeaderProxy(
QList<Net::HeaderPair>{ { "Content-Type", "application/x-www-form-urlencoded" },
{ "Authorization", QString("Client-ID %1").arg(BuildConfig.IMGUR_CLIENT_ID).toStdString().c_str() },
{ "Accept", "application/json" } });
addHeaderProxy(api_headers);
}
void ImgurAlbumCreation::downloadError([[maybe_unused]] QNetworkReply::NetworkError error)
auto ImgurAlbumCreation::Sink::init(QNetworkRequest& request) -> Task::State
{
qDebug() << m_reply->errorString();
m_state = State::Failed;
m_output.clear();
return Task::State::Running;
};
auto ImgurAlbumCreation::Sink::write(QByteArray& data) -> Task::State
{
m_output.append(data);
return Task::State::Running;
}
void ImgurAlbumCreation::downloadFinished()
auto ImgurAlbumCreation::Sink::abort() -> Task::State
{
if (m_state != State::Failed) {
QByteArray data = m_reply->readAll();
m_reply.reset();
QJsonParseError jsonError;
QJsonDocument doc = QJsonDocument::fromJson(data, &jsonError);
if (jsonError.error != QJsonParseError::NoError) {
qDebug() << jsonError.errorString();
emitFailed();
return;
}
auto object = doc.object();
if (!object.value("success").toBool()) {
qDebug() << doc.toJson();
emitFailed();
return;
}
m_deleteHash = object.value("data").toObject().value("deletehash").toString();
m_id = object.value("data").toObject().value("id").toString();
m_state = State::Succeeded;
emit succeeded();
return;
} else {
qDebug() << m_reply->readAll();
m_reply.reset();
emitFailed();
return;
m_output.clear();
return Task::State::Failed;
}
auto ImgurAlbumCreation::Sink::finalize(QNetworkReply&) -> Task::State
{
QJsonParseError jsonError;
QJsonDocument doc = QJsonDocument::fromJson(m_output, &jsonError);
if (jsonError.error != QJsonParseError::NoError) {
qDebug() << jsonError.errorString();
return Task::State::Failed;
}
}
void ImgurAlbumCreation::downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
{
setProgress(bytesReceived, bytesTotal);
emit progress(bytesReceived, bytesTotal);
}
auto object = doc.object();
if (!object.value("success").toBool()) {
qDebug() << doc.toJson();
return Task::State::Failed;
}
m_result->deleteHash = object.value("data").toObject().value("deletehash").toString();
m_result->id = object.value("data").toObject().value("id").toString();
return Task::State::Succeeded;
}

View File

@ -36,34 +36,39 @@
#pragma once
#include "Screenshot.h"
#include "net/NetAction.h"
#include "net/NetRequest.h"
typedef shared_qobject_ptr<class ImgurAlbumCreation> ImgurAlbumCreationPtr;
class ImgurAlbumCreation : public NetAction {
class ImgurAlbumCreation : public Net::NetRequest {
public:
explicit ImgurAlbumCreation(QList<ScreenShot::Ptr> screenshots);
static ImgurAlbumCreationPtr make(QList<ScreenShot::Ptr> screenshots)
{
return ImgurAlbumCreationPtr(new ImgurAlbumCreation(screenshots));
}
virtual ~ImgurAlbumCreation() = default;
QString deleteHash() const { return m_deleteHash; }
QString id() const { return m_id; }
struct Result {
QString deleteHash;
QString id;
};
void init() override{};
class Sink : public Net::Sink {
public:
Sink(std::shared_ptr<Result> res) : m_result(res){};
virtual ~Sink() = default;
protected slots:
void downloadProgress(qint64 bytesReceived, qint64 bytesTotal) override;
void downloadError(QNetworkReply::NetworkError error) override;
void downloadFinished() override;
void downloadReadyRead() override {}
public:
auto init(QNetworkRequest& request) -> Task::State override;
auto write(QByteArray& data) -> Task::State override;
auto abort() -> Task::State override;
auto finalize(QNetworkReply& reply) -> Task::State override;
auto hasLocalData() -> bool override { return false; }
public slots:
void executeTask() override;
private:
std::shared_ptr<Result> m_result;
QByteArray m_output;
};
static NetRequest::Ptr make(std::shared_ptr<Result> output, QList<ScreenShot::Ptr> screenshots);
QNetworkReply* getReply(QNetworkRequest& request) override;
void init() override;
private:
QList<ScreenShot::Ptr> m_screenshots;
QString m_deleteHash;
QString m_id;
};

View File

@ -35,8 +35,8 @@
*/
#include "ImgurUpload.h"
#include "Application.h"
#include "BuildConfig.h"
#include "net/StaticHeaderProxy.h"
#include <QDebug>
#include <QFile>
@ -47,104 +47,84 @@
#include <QNetworkRequest>
#include <QUrl>
ImgurUpload::ImgurUpload(ScreenShot::Ptr shot) : NetAction(), m_shot(shot)
void ImgurUpload::init()
{
m_url = BuildConfig.IMGUR_BASE_URL + "upload.json";
m_state = State::Inactive;
qDebug() << "Setting up imgur upload";
auto api_headers = new Net::StaticHeaderProxy(
QList<Net::HeaderPair>{ { "Authorization", QString("Client-ID %1").arg(BuildConfig.IMGUR_CLIENT_ID).toStdString().c_str() },
{ "Accept", "application/json" } });
addHeaderProxy(api_headers);
}
void ImgurUpload::executeTask()
QNetworkReply* ImgurUpload::getReply(QNetworkRequest& request)
{
finished = false;
m_state = Task::State::Running;
QNetworkRequest request(m_url);
request.setHeader(QNetworkRequest::UserAgentHeader, APPLICATION->getUserAgentUncached().toUtf8());
request.setRawHeader("Authorization", QString("Client-ID %1").arg(BuildConfig.IMGUR_CLIENT_ID).toStdString().c_str());
request.setRawHeader("Accept", "application/json");
auto file = new QFile(m_fileInfo.absoluteFilePath());
QFile f(m_shot->m_file.absoluteFilePath());
if (!f.open(QFile::ReadOnly)) {
if (!file->open(QFile::ReadOnly)) {
emitFailed();
return;
return nullptr;
}
QHttpMultiPart* multipart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
file->setParent(multipart);
QHttpPart filePart;
filePart.setBody(f.readAll().toBase64());
filePart.setBodyDevice(file);
filePart.setHeader(QNetworkRequest::ContentTypeHeader, "image/png");
filePart.setHeader(QNetworkRequest::ContentDispositionHeader, "form-data; name=\"image\"");
multipart->append(filePart);
QHttpPart typePart;
typePart.setHeader(QNetworkRequest::ContentDispositionHeader, "form-data; name=\"type\"");
typePart.setBody("base64");
typePart.setBody("file");
multipart->append(typePart);
QHttpPart namePart;
namePart.setHeader(QNetworkRequest::ContentDispositionHeader, "form-data; name=\"name\"");
namePart.setBody(m_shot->m_file.baseName().toUtf8());
namePart.setBody(m_fileInfo.baseName().toUtf8());
multipart->append(namePart);
QNetworkReply* rep = m_network->post(request, multipart);
return m_network->post(request, multipart);
};
m_reply.reset(rep);
connect(rep, &QNetworkReply::uploadProgress, this, &ImgurUpload::downloadProgress);
connect(rep, &QNetworkReply::finished, this, &ImgurUpload::downloadFinished);
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) // QNetworkReply::errorOccurred added in 5.15
connect(rep, &QNetworkReply::errorOccurred, this, &ImgurUpload::downloadError);
#else
connect(rep, QOverload<QNetworkReply::NetworkError>::of(&QNetworkReply::error), this, &ImgurUpload::downloadError);
#endif
connect(rep, &QNetworkReply::sslErrors, this, &ImgurUpload::sslErrors);
auto ImgurUpload::Sink::init(QNetworkRequest& request) -> Task::State
{
m_output.clear();
return Task::State::Running;
};
auto ImgurUpload::Sink::write(QByteArray& data) -> Task::State
{
m_output.append(data);
return Task::State::Running;
}
void ImgurUpload::downloadError([[maybe_unused]] QNetworkReply::NetworkError error)
auto ImgurUpload::Sink::abort() -> Task::State
{
qCritical() << "ImgurUpload failed with error" << m_reply->errorString() << "Server reply:\n" << m_reply->readAll();
if (finished) {
qCritical() << "Double finished ImgurUpload!";
return;
}
m_state = Task::State::Failed;
finished = true;
m_reply.reset();
emitFailed();
m_output.clear();
return Task::State::Failed;
}
void ImgurUpload::downloadFinished()
auto ImgurUpload::Sink::finalize(QNetworkReply&) -> Task::State
{
if (finished) {
qCritical() << "Double finished ImgurUpload!";
return;
}
QByteArray data = m_reply->readAll();
m_reply.reset();
QJsonParseError jsonError;
QJsonDocument doc = QJsonDocument::fromJson(data, &jsonError);
QJsonDocument doc = QJsonDocument::fromJson(m_output, &jsonError);
if (jsonError.error != QJsonParseError::NoError) {
qDebug() << "imgur server did not reply with JSON" << jsonError.errorString();
finished = true;
m_reply.reset();
emitFailed();
return;
return Task::State::Failed;
}
auto object = doc.object();
if (!object.value("success").toBool()) {
qDebug() << "Screenshot upload not successful:" << doc.toJson();
finished = true;
m_reply.reset();
emitFailed();
return;
return Task::State::Failed;
}
m_shot->m_imgurId = object.value("data").toObject().value("id").toString();
m_shot->m_url = object.value("data").toObject().value("link").toString();
m_shot->m_imgurDeleteHash = object.value("data").toObject().value("deletehash").toString();
m_state = Task::State::Succeeded;
finished = true;
emit succeeded();
return;
return Task::State::Succeeded;
}
void ImgurUpload::downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
Net::NetRequest::Ptr ImgurUpload::make(ScreenShot::Ptr m_shot)
{
setProgress(bytesReceived, bytesTotal);
emit progress(bytesReceived, bytesTotal);
auto up = makeShared<ImgurUpload>(m_shot->m_file);
up->m_url = std::move(BuildConfig.IMGUR_BASE_URL + "upload.json");
up->m_sink.reset(new Sink(m_shot));
return up;
}

View File

@ -35,27 +35,36 @@
#pragma once
#include <QFileInfo>
#include "Screenshot.h"
#include "net/NetAction.h"
#include "net/NetRequest.h"
class ImgurUpload : public NetAction {
class ImgurUpload : public Net::NetRequest {
public:
using Ptr = shared_qobject_ptr<ImgurUpload>;
class Sink : public Net::Sink {
public:
Sink(ScreenShot::Ptr shot) : m_shot(shot){};
virtual ~Sink() = default;
explicit ImgurUpload(ScreenShot::Ptr shot);
static Ptr make(ScreenShot::Ptr shot) { return Ptr(new ImgurUpload(shot)); }
void init() override{};
public:
auto init(QNetworkRequest& request) -> Task::State override;
auto write(QByteArray& data) -> Task::State override;
auto abort() -> Task::State override;
auto finalize(QNetworkReply& reply) -> Task::State override;
auto hasLocalData() -> bool override { return false; }
protected slots:
void downloadProgress(qint64 bytesReceived, qint64 bytesTotal) override;
void downloadError(QNetworkReply::NetworkError error) override;
void downloadFinished() override;
void downloadReadyRead() override {}
private:
ScreenShot::Ptr m_shot;
QByteArray m_output;
};
ImgurUpload(QFileInfo info) : m_fileInfo(info) {}
virtual ~ImgurUpload() = default;
public slots:
void executeTask() override;
static NetRequest::Ptr make(ScreenShot::Ptr m_shot);
void init() override;
private:
ScreenShot::Ptr m_shot;
bool finished = true;
virtual QNetworkReply* getReply(QNetworkRequest&) override;
const QFileInfo m_fileInfo;
};

View File

@ -26,8 +26,8 @@
class Setting;
class SettingsObject;
typedef std::shared_ptr<SettingsObject> SettingsObjectPtr;
typedef std::weak_ptr<SettingsObject> SettingsObjectWeakPtr;
using SettingsObjectPtr = std::shared_ptr<SettingsObject>;
using SettingsObjectWeakPtr = std::weak_ptr<SettingsObject>;
/*!
* \brief The SettingsObject handles communicating settings between the application and a

View File

@ -77,7 +77,7 @@ struct TaskStepProgress {
Q_DECLARE_METATYPE(TaskStepProgress)
typedef QList<std::shared_ptr<TaskStepProgress>> TaskStepProgressList;
using TaskStepProgressList = QList<std::shared_ptr<TaskStepProgress>>;
class Task : public QObject, public QRunnable {
Q_OBJECT

View File

@ -85,6 +85,7 @@ QString getCreditsHtml()
stream << QString("<p>TayouVR %1</p>\n").arg(getGitHub("TayouVR"));
stream << QString("<p>TheKodeToad %1</p>\n").arg(getGitHub("TheKodeToad"));
stream << QString("<p>getchoo %1</p>\n").arg(getGitHub("getchoo"));
stream << QString("<p>Alexandru Tripon (Trial97) %1</p>\n").arg(getGitHub("Trial97"));
stream << "<br />\n";
// TODO: possibly retrieve from git history at build time?
@ -100,7 +101,7 @@ QString getCreditsHtml()
stream << "<h3>" << QObject::tr("With thanks to", "About Credits") << "</h3>\n";
stream << QString("<p>Boba %1</p>\n").arg(getWebsite("https://bobaonline.neocities.org/"));
stream << QString("<p>Davi Rafael %1</p>\n").arg(getWebsite("https://auti.one/"));
stream << QString("<p>Fulmine %1</p>\n").arg(getWebsite("https://www.fulmine.xyz/"));
stream << QString("<p>Fulmine %1</p>\n").arg(getWebsite("https://fulmine.xyz/"));
stream << QString("<p>ely %1</p>\n").arg(getGitHub("elyrodso"));
stream << QString("<p>gon sawa %1</p>\n").arg(getGitHub("gonsawa"));
stream << QString("<p>Pankakes</p>\n");

View File

@ -13,7 +13,6 @@ enum class ResourceProvider;
class Mod;
class NetJob;
class ModUpdateDialog;
class ChooseProviderDialog : public QDialog {
Q_OBJECT

View File

@ -43,7 +43,7 @@
#include "FileIgnoreProxy.h"
class BaseInstance;
typedef std::shared_ptr<BaseInstance> InstancePtr;
using InstancePtr = std::shared_ptr<BaseInstance>;
namespace Ui {
class ExportInstanceDialog;

View File

@ -214,10 +214,11 @@ void ExportToModListDialog::addExtra(ExportToModList::OptionalData option)
void ExportToModListDialog::enableCustom(bool enabled)
{
ui->authorsCheckBox->setHidden(enabled);
ui->versionCheckBox->setHidden(enabled);
ui->urlCheckBox->setHidden(enabled);
ui->authorsButton->setHidden(!enabled);
ui->versionCheckBox->setHidden(enabled);
ui->versionButton->setHidden(!enabled);
ui->urlCheckBox->setHidden(enabled);
ui->urlButton->setHidden(!enabled);
}

View File

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>650</width>
<height>446</height>
<height>522</height>
</rect>
</property>
<property name="windowTitle">
@ -61,18 +61,37 @@
</item>
<item row="1" column="0">
<widget class="QGroupBox" name="templateGroup">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Template</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QTextEdit" name="templateText"/>
<widget class="QTextEdit" name="templateText">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="1" column="1">
<widget class="QGroupBox" name="optionsGroup">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Optional Info</string>
</property>

View File

@ -105,8 +105,16 @@ void MSALoginDialog::showVerificationUriAndCode(const QUrl& uri, const QString&
QString urlString = uri.toString();
QString linkString = QString("<a href=\"%1\">%2</a>").arg(urlString, urlString);
ui->label->setText(
tr("<p>Please open up %1 in a browser and put in the code <b>%2</b> to proceed with login.</p>").arg(linkString, code));
if (urlString == "https://www.microsoft.com/link" && !code.isEmpty()) {
urlString += QString("?otc=%1").arg(code);
DesktopServices::openUrl(urlString);
ui->label->setText(tr("<p>Please login in the opened browser. If no browser was opened, please open up %1 in "
"a browser and put in the code <b>%2</b> to proceed with login.</p>")
.arg(linkString, code));
} else {
ui->label->setText(
tr("<p>Please open up %1 in a browser and put in the code <b>%2</b> to proceed with login.</p>").arg(linkString, code));
}
ui->actionButton->setVisible(true);
connect(ui->actionButton, &QPushButton::clicked, [=]() {
DesktopServices::openUrl(uri);

View File

@ -39,7 +39,8 @@ static std::optional<ModPlatform::ModLoaderTypes> mcLoaders(BaseInstance* inst)
ModUpdateDialog::ModUpdateDialog(QWidget* parent,
BaseInstance* instance,
const std::shared_ptr<ModFolderModel> mods,
QList<Mod*>& search_for)
QList<Mod*>& search_for,
bool includeDeps)
: ReviewMessageBox(parent, tr("Confirm mods to update"), "")
, m_parent(parent)
, m_mod_model(mods)
@ -47,6 +48,7 @@ ModUpdateDialog::ModUpdateDialog(QWidget* parent,
, m_second_try_metadata(
new ConcurrentTask(nullptr, "Second Metadata Search", APPLICATION->settings()->get("NumberOfConcurrentTasks").toInt()))
, m_instance(instance)
, m_include_deps(includeDeps)
{
ReviewMessageBox::setGeometry(0, 0, 800, 600);
@ -186,7 +188,7 @@ void ModUpdateDialog::checkCandidates()
}
}
{ // dependencies
if (m_include_deps && !APPLICATION->settings()->get("ModDependenciesDisabled").toBool()) { // dependencies
auto depTask = makeShared<GetModDependenciesTask>(this, m_instance, m_mod_model.get(), selectedVers);
connect(depTask.get(), &Task::failed, this,

View File

@ -19,7 +19,8 @@ class ModUpdateDialog final : public ReviewMessageBox {
explicit ModUpdateDialog(QWidget* parent,
BaseInstance* instance,
const std::shared_ptr<ModFolderModel> mod_model,
QList<Mod*>& search_for);
QList<Mod*>& search_for,
bool includeDeps);
void checkCandidates();
@ -61,4 +62,5 @@ class ModUpdateDialog final : public ReviewMessageBox {
bool m_no_updates = false;
bool m_aborted = false;
bool m_include_deps = false;
};

View File

@ -271,13 +271,15 @@ QList<BasePage*> ModDownloadDialog::getPages()
GetModDependenciesTask::Ptr ModDownloadDialog::getModDependenciesTask()
{
if (auto model = dynamic_cast<ModFolderModel*>(getBaseModel().get()); model) {
QList<std::shared_ptr<GetModDependenciesTask::PackDependency>> selectedVers;
for (auto& selected : getTasks()) {
selectedVers.append(std::make_shared<GetModDependenciesTask::PackDependency>(selected->getPack(), selected->getVersion()));
}
if (!APPLICATION->settings()->get("ModDependenciesDisabled").toBool()) { // dependencies
if (auto model = dynamic_cast<ModFolderModel*>(getBaseModel().get()); model) {
QList<std::shared_ptr<GetModDependenciesTask::PackDependency>> selectedVers;
for (auto& selected : getTasks()) {
selectedVers.append(std::make_shared<GetModDependenciesTask::PackDependency>(selected->getPack(), selected->getVersion()));
}
return makeShared<GetModDependenciesTask>(this, m_instance, model, selectedVers);
return makeShared<GetModDependenciesTask>(this, m_instance, model, selectedVers);
}
}
return nullptr;
}

View File

@ -59,7 +59,7 @@ class AccessibleInstanceView : public QAccessibleTableInterface, public QAccessi
protected:
// maybe vector
typedef QHash<int, QAccessible::Id> ChildCache;
using ChildCache = QHash<int, QAccessible::Id>;
mutable ChildCache childToId;
virtual ~AccessibleInstanceView();

View File

@ -39,6 +39,7 @@
#include <QApplication>
#include <QCache>
#include <QDrag>
#include <QFont>
#include <QListView>
#include <QMimeData>
#include <QMouseEvent>
@ -277,12 +278,14 @@ void InstanceView::mousePressEvent(QMouseEvent* event)
m_pressedAlreadySelected = selectionModel()->isSelected(m_pressedIndex);
m_pressedPosition = geometryPos;
VisualGroup::HitResults hitResult;
m_pressedCategory = categoryAt(geometryPos, hitResult);
if (m_pressedCategory && hitResult & VisualGroup::CheckboxHit) {
setState(m_pressedCategory->collapsed ? ExpandingState : CollapsingState);
event->accept();
return;
if (event->button() == Qt::LeftButton) {
VisualGroup::HitResults hitResult;
m_pressedCategory = categoryAt(geometryPos, hitResult);
if (m_pressedCategory && hitResult & VisualGroup::CheckboxHit) {
setState(m_pressedCategory->collapsed ? ExpandingState : CollapsingState);
event->accept();
return;
}
}
if (index.isValid() && (index.flags() & Qt::ItemIsEnabled)) {
@ -365,10 +368,7 @@ void InstanceView::mouseReleaseEvent(QMouseEvent* event)
VisualGroup::HitResults hitResult;
bool click =
(index == m_pressedIndex && index.isValid()) || (m_pressedCategory && m_pressedCategory == categoryAt(geometryPos, hitResult));
if (click && m_pressedCategory) {
if (event->button() == Qt::LeftButton && m_pressedCategory != nullptr && m_pressedCategory == categoryAt(geometryPos, hitResult)) {
if (state() == ExpandingState) {
m_pressedCategory->collapsed = false;
emit groupStateChanged(m_pressedCategory->text, false);
@ -396,7 +396,7 @@ void InstanceView::mouseReleaseEvent(QMouseEvent* event)
setState(NoState);
if (click) {
if (index == m_pressedIndex && index.isValid()) {
if (event->button() == Qt::LeftButton) {
emit clicked(index);
}
@ -478,6 +478,38 @@ void InstanceView::paintEvent([[maybe_unused]] QPaintEvent* event)
#endif
option.widget = this;
if (model()->rowCount() == 0) {
painter.save();
const QString line1 = tr("Welcome!");
const QString line2 = tr("Click \"Add Instance\" to get started.");
auto rect = this->viewport()->rect();
auto font = option.font;
font.setPointSize(37);
painter.setFont(font);
auto fm = painter.fontMetrics();
if (rect.height() <= (fm.height() * 5) || rect.width() <= fm.horizontalAdvance(line2)) {
auto s = rect.height() / (5. * fm.height());
auto sx = rect.width() * 1. / fm.horizontalAdvance(line2);
if (s >= sx)
s = sx;
auto ps = font.pointSize() * s;
if (ps <= 0)
ps = 1;
font.setPointSize(ps);
painter.setFont(font);
fm = painter.fontMetrics();
}
// text
rect.setTop(rect.top() + fm.height() * 1.5);
painter.drawText(rect, Qt::AlignHCenter, line1);
rect.setTop(rect.top() + fm.height());
painter.drawText(rect, Qt::AlignHCenter, line2);
painter.restore();
return;
}
int wpWidth = viewport()->width();
option.rect.setWidth(wpWidth);
for (int i = 0; i < m_groups.size(); ++i) {

View File

@ -77,4 +77,4 @@ class BasePage {
bool isOpened = false;
};
typedef std::shared_ptr<BasePage> BasePagePtr;
using BasePagePtr = std::shared_ptr<BasePage>;

View File

@ -26,7 +26,7 @@ class BasePageProvider {
};
class GenericPageProvider : public BasePageProvider {
typedef std::function<BasePage*()> PageCreator;
using PageCreator = std::function<BasePage*()>;
public:
explicit GenericPageProvider(const QString& dialogTitle) : m_dialogTitle(dialogTitle) {}

View File

@ -42,22 +42,17 @@
#include <QDebug>
#include "net/NetJob.h"
#include "ui/dialogs/CustomMessageBox.h"
#include "ui/dialogs/MSALoginDialog.h"
#include "ui/dialogs/OfflineLoginDialog.h"
#include "ui/dialogs/ProgressDialog.h"
#include "ui/dialogs/SkinUploadDialog.h"
#include "minecraft/auth/AccountTask.h"
#include "minecraft/services/SkinDelete.h"
#include "tasks/Task.h"
#include "Application.h"
#include "BuildConfig.h"
AccountListPage::AccountListPage(QWidget* parent) : QMainWindow(parent), ui(new Ui::AccountListPage)
{
ui->setupUi(this);
@ -172,6 +167,12 @@ void AccountListPage::on_actionAddOffline_triggered()
void AccountListPage::on_actionRemove_triggered()
{
auto response = CustomMessageBox::selectable(this, tr("Remove account?"), tr("Do you really want to delete this account?"),
QMessageBox::Question, QMessageBox::Yes | QMessageBox::No, QMessageBox::No)
->exec();
if (response != QMessageBox::Yes) {
return;
}
QModelIndexList selection = ui->listView->selectionModel()->selectedIndexes();
if (selection.size() > 0) {
QModelIndex selected = selection.first();
@ -230,6 +231,7 @@ void AccountListPage::updateButtonStates()
ui->actionNoDefault->setEnabled(true);
ui->actionNoDefault->setChecked(false);
}
ui->listView->resizeColumnToContents(3);
}
void AccountListPage::on_actionUploadSkin_triggered()

View File

@ -0,0 +1,71 @@
// SPDX-License-Identifier: GPL-3.0-only
/*
* Prism Launcher - Minecraft Launcher
* Copyright (C) 2023 TheKodeToad <TheKodeToad@proton.me>
*
* 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 <https://www.gnu.org/licenses/>.
*/
#include <QTabBar>
#include <QTabWidget>
#include <QVBoxLayout>
#include "EnvironmentVariablesPage.h"
EnvironmentVariablesPage::EnvironmentVariablesPage(QWidget* parent) : QWidget(parent)
{
auto verticalLayout = new QVBoxLayout(this);
verticalLayout->setObjectName(QStringLiteral("verticalLayout"));
verticalLayout->setContentsMargins(0, 0, 0, 0);
auto tabWidget = new QTabWidget(this);
tabWidget->setObjectName(QStringLiteral("tabWidget"));
variables = new EnvironmentVariables(this);
variables->setContentsMargins(6, 6, 6, 6);
tabWidget->addTab(variables, "Foo");
tabWidget->tabBar()->hide();
verticalLayout->addWidget(tabWidget);
variables->initialize(false, false, APPLICATION->settings()->get("Env").toMap());
}
QString EnvironmentVariablesPage::displayName() const
{
return tr("Environment Variables");
}
QIcon EnvironmentVariablesPage::icon() const
{
return APPLICATION->getThemedIcon("environment-variables");
}
QString EnvironmentVariablesPage::id() const
{
return "environment-variables";
}
QString EnvironmentVariablesPage::helpPage() const
{
return "Environment-variables";
}
bool EnvironmentVariablesPage::apply()
{
APPLICATION->settings()->set("Env", variables->value());
return true;
}
void EnvironmentVariablesPage::retranslate()
{
variables->retranslate();
}

View File

@ -0,0 +1,42 @@
// SPDX-License-Identifier: GPL-3.0-only
/*
* Prism Launcher - Minecraft Launcher
* Copyright (C) 2023 TheKodeToad <TheKodeToad@proton.me>
*
* 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 <https://www.gnu.org/licenses/>.
*/
#pragma once
#include <Application.h>
#include "ui/pages/BasePage.h"
#include "ui/widgets/EnvironmentVariables.h"
class EnvironmentVariablesPage : public QWidget, public BasePage {
Q_OBJECT
public:
explicit EnvironmentVariablesPage(QWidget* parent = nullptr);
QString displayName() const override;
QIcon icon() const override;
QString id() const override;
QString helpPage() const override;
bool apply() override;
void retranslate() override;
private:
EnvironmentVariables* variables;
};

View File

@ -223,6 +223,7 @@ void LauncherPage::applySettings()
// Mods
s->set("ModMetadataDisabled", ui->metadataDisableBtn->isChecked());
s->set("ModDependenciesDisabled", ui->dependenciesDisableBtn->isChecked());
}
void LauncherPage::loadSettings()
{
@ -278,6 +279,7 @@ void LauncherPage::loadSettings()
// Mods
ui->metadataDisableBtn->setChecked(s->get("ModMetadataDisabled").toBool());
ui->metadataWarningLabel->setHidden(!ui->metadataDisableBtn->isChecked());
ui->dependenciesDisableBtn->setChecked(s->get("ModDependenciesDisabled").toBool());
}
void LauncherPage::refreshFontPreview()

View File

@ -186,6 +186,16 @@
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="dependenciesDisableBtn">
<property name="toolTip">
<string>Disable the automatic detection, installation, and updating of mod dependencies.</string>
</property>
<property name="text">
<string>Disable automatic mod dependency management</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>

View File

@ -42,6 +42,7 @@
#include "minecraft/mod/ResourceFolderModel.h"
#include "ui/GuiUtil.h"
#include <QHeaderView>
#include <QKeyEvent>
#include <QMenu>
#include <algorithm>
@ -95,7 +96,8 @@ ExternalResourcesPage::ExternalResourcesPage(BaseInstance* instance, std::shared
connect(viewHeader, &QHeaderView::customContextMenuRequested, this, &ExternalResourcesPage::ShowHeaderContextMenu);
m_model->loadHiddenColumns(ui->treeView);
m_model->loadColumns(ui->treeView);
connect(ui->treeView->header(), &QHeaderView::sectionResized, this, [this] { m_model->saveColumns(ui->treeView); });
}
ExternalResourcesPage::~ExternalResourcesPage()

View File

@ -70,6 +70,9 @@
</layout>
</widget>
<widget class="WideBar" name="actionsToolbar">
<property name="useDefaultAction" stdset="0">
<bool>true</bool>
</property>
<property name="windowTitle">
<string>Actions</string>
</property>
@ -146,17 +149,6 @@
<string>Download a new resource</string>
</property>
</action>
<action name="actionUpdateItem">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Check for &amp;Updates</string>
</property>
<property name="toolTip">
<string>Try to check or update all selected resources (all resources if none are selected)</string>
</property>
</action>
<action name="actionVisitItemPage">
<property name="enabled">
<bool>false</bool>
@ -168,15 +160,15 @@
<string>Go to mods home page</string>
</property>
</action>
<action name="actionRemoveItemMetadata">
<action name="actionUpdateItem">
<property name="enabled">
<bool>false</bool>
<bool>true</bool>
</property>
<property name="text">
<string>Remove metadata</string>
<string>Check for &amp;Updates</string>
</property>
<property name="toolTip">
<string>Remove mod's metadata</string>
<string>Try to check or update all selected resources (all resources if none are selected)</string>
</property>
</action>
</widget>

View File

@ -90,6 +90,9 @@ void InstanceSettingsPage::globalSettingsButtonClicked(bool)
case 2:
APPLICATION->ShowGlobalSettings(this, "custom-commands");
return;
case 3:
APPLICATION->ShowGlobalSettings(this, "environment-variables");
return;
default:
APPLICATION->ShowGlobalSettings(this, "minecraft-settings");
return;
@ -199,6 +202,14 @@ void InstanceSettingsPage::applySettings()
m_settings->reset("PostExitCommand");
}
// Environment Variables
auto env = ui->environmentVariables->override();
m_settings->set("OverrideEnv", env);
if (env)
m_settings->set("Env", ui->environmentVariables->value());
else
m_settings->reset("Env");
// Workarounds
bool workarounds = ui->nativeWorkaroundsGroupBox->isChecked();
m_settings->set("OverrideNativeWorkarounds", workarounds);
@ -318,6 +329,9 @@ void InstanceSettingsPage::loadSettings()
ui->customCommands->initialize(true, m_settings->get("OverrideCommands").toBool(), m_settings->get("PreLaunchCommand").toString(),
m_settings->get("WrapperCommand").toString(), m_settings->get("PostExitCommand").toString());
// Environment variables
ui->environmentVariables->initialize(true, m_settings->get("OverrideEnv").toBool(), m_settings->get("Env").toMap());
// Workarounds
ui->nativeWorkaroundsGroupBox->setChecked(m_settings->get("OverrideNativeWorkarounds").toBool());
ui->useNativeGLFWCheck->setChecked(m_settings->get("UseNativeGLFW").toBool());
@ -484,6 +498,7 @@ void InstanceSettingsPage::retranslate()
{
ui->retranslateUi(this);
ui->customCommands->retranslate(); // TODO: why is this seperate from the others?
ui->environmentVariables->retranslate();
}
void InstanceSettingsPage::updateThresholds()

View File

@ -35,13 +35,10 @@
</item>
<item>
<widget class="QTabWidget" name="settingsTabs">
<property name="tabShape">
<enum>QTabWidget::Rounded</enum>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="minecraftTab">
<widget class="QWidget" name="minecraftPage">
<attribute name="title">
<string notr="true">Java</string>
</attribute>
@ -254,7 +251,7 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="javaTab">
<widget class="QWidget" name="javaPage">
<attribute name="title">
<string>Game windows</string>
</attribute>
@ -414,7 +411,7 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="tab">
<widget class="QWidget" name="customCommandsPage">
<attribute name="title">
<string>Custom commands</string>
</attribute>
@ -424,6 +421,16 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="environmentVariablesPage">
<attribute name="title">
<string>Environment variables</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_16">
<item>
<widget class="EnvironmentVariables" name="environmentVariables" native="true"/>
</item>
</layout>
</widget>
<widget class="QWidget" name="workaroundsPage">
<attribute name="title">
<string>Workarounds</string>
@ -736,6 +743,12 @@
<header>ui/widgets/CustomCommands.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>EnvironmentVariables</class>
<extends>QWidget</extends>
<header>ui/widgets/EnvironmentVariables.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>openGlobalJavaSettingsButton</tabstop>

View File

@ -84,50 +84,71 @@ ModFolderPage::ModFolderPage(BaseInstance* inst, std::shared_ptr<ModFolderModel>
connect(ui->actionDownloadItem, &QAction::triggered, this, &ModFolderPage::installMods);
// update menu
auto updateMenu = ui->actionUpdateItem->menu();
if (updateMenu) {
updateMenu->clear();
} else {
updateMenu = new QMenu(this);
}
auto update = updateMenu->addAction(tr("Check for Updates"));
update->setToolTip(tr("Try to check or update all selected mods (all mods if none are selected)"));
connect(update, &QAction::triggered, this, &ModFolderPage::updateMods);
auto updateWithDeps = updateMenu->addAction(tr("Verify Dependencies"));
updateWithDeps->setToolTip(
tr("Try to update and check for missing dependencies all selected mods (all mods if none are selected)"));
connect(updateWithDeps, &QAction::triggered, this, [this] { updateMods(true); });
auto depsDisabled = APPLICATION->settings()->getSetting("ModDependenciesDisabled");
updateWithDeps->setVisible(!depsDisabled->get().toBool());
connect(depsDisabled.get(), &Setting::SettingChanged, this,
[updateWithDeps](const Setting& setting, QVariant value) { updateWithDeps->setVisible(!value.toBool()); });
auto actionRemoveItemMetadata = updateMenu->addAction(tr("Reset update metadata"));
actionRemoveItemMetadata->setToolTip(tr("Remove mod's metadata"));
connect(actionRemoveItemMetadata, &QAction::triggered, this, &ModFolderPage::deleteModMetadata);
actionRemoveItemMetadata->setEnabled(false);
ui->actionUpdateItem->setMenu(updateMenu);
ui->actionUpdateItem->setToolTip(tr("Try to check or update all selected mods (all mods if none are selected)"));
ui->actionsToolbar->insertActionAfter(ui->actionAddItem, ui->actionUpdateItem);
connect(ui->actionUpdateItem, &QAction::triggered, this, &ModFolderPage::updateMods);
ui->actionsToolbar->insertActionBefore(ui->actionAddItem, ui->actionUpdateItem);
ui->actionVisitItemPage->setToolTip(tr("Go to mod's home page"));
ui->actionsToolbar->addAction(ui->actionVisitItemPage);
connect(ui->actionVisitItemPage, &QAction::triggered, this, &ModFolderPage::visitModPages);
ui->actionRemoveItemMetadata->setToolTip(tr("Remove mod's metadata"));
ui->actionsToolbar->insertActionAfter(ui->actionRemoveItem, ui->actionRemoveItemMetadata);
connect(ui->actionRemoveItemMetadata, &QAction::triggered, this, &ModFolderPage::deleteModMetadata);
auto check_allow_update = [this] { return ui->treeView->selectionModel()->hasSelection() || !m_model->empty(); };
connect(ui->treeView->selectionModel(), &QItemSelectionModel::selectionChanged, this, [this, check_allow_update] {
ui->actionUpdateItem->setEnabled(check_allow_update());
connect(ui->treeView->selectionModel(), &QItemSelectionModel::selectionChanged, this,
[this, check_allow_update, actionRemoveItemMetadata] {
ui->actionUpdateItem->setEnabled(check_allow_update());
auto selection = m_filterModel->mapSelectionToSource(ui->treeView->selectionModel()->selection()).indexes();
auto mods_list = m_model->selectedMods(selection);
auto selected = std::count_if(mods_list.cbegin(), mods_list.cend(),
[](Mod* v) { return v->metadata() != nullptr || v->homeurl().size() != 0; });
if (selected <= 1) {
ui->actionVisitItemPage->setText(tr("Visit mod's page"));
ui->actionVisitItemPage->setToolTip(tr("Go to mod's home page"));
auto selection = m_filterModel->mapSelectionToSource(ui->treeView->selectionModel()->selection()).indexes();
auto mods_list = m_model->selectedMods(selection);
auto selected = std::count_if(mods_list.cbegin(), mods_list.cend(),
[](Mod* v) { return v->metadata() != nullptr || v->homeurl().size() != 0; });
if (selected <= 1) {
ui->actionVisitItemPage->setText(tr("Visit mod's page"));
ui->actionVisitItemPage->setToolTip(tr("Go to mod's home page"));
ui->actionRemoveItemMetadata->setToolTip(tr("Remove mod's metadata"));
} else {
ui->actionVisitItemPage->setText(tr("Visit mods' pages"));
ui->actionVisitItemPage->setToolTip(tr("Go to the pages of the selected mods"));
} else {
ui->actionVisitItemPage->setText(tr("Visit mods' pages"));
ui->actionVisitItemPage->setToolTip(tr("Go to the pages of the selected mods"));
}
ui->actionVisitItemPage->setEnabled(selected != 0);
actionRemoveItemMetadata->setEnabled(selected != 0);
});
ui->actionRemoveItemMetadata->setToolTip(tr("Remove mods' metadata"));
}
ui->actionVisitItemPage->setEnabled(selected != 0);
ui->actionRemoveItemMetadata->setEnabled(selected != 0);
});
auto updateButtons = [this, check_allow_update] { ui->actionUpdateItem->setEnabled(check_allow_update()); };
connect(mods.get(), &ModFolderModel::rowsInserted, this, updateButtons);
connect(mods.get(), &ModFolderModel::rowsInserted, this,
[this, check_allow_update] { ui->actionUpdateItem->setEnabled(check_allow_update()); });
connect(mods.get(), &ModFolderModel::rowsRemoved, this, updateButtons);
connect(mods.get(), &ModFolderModel::rowsRemoved, this,
[this, check_allow_update] { ui->actionUpdateItem->setEnabled(check_allow_update()); });
connect(mods.get(), &ModFolderModel::updateFinished, this,
[this, check_allow_update] { ui->actionUpdateItem->setEnabled(check_allow_update()); });
connect(mods.get(), &ModFolderModel::updateFinished, this, updateButtons);
}
}
@ -204,7 +225,7 @@ void ModFolderPage::installMods()
}
}
void ModFolderPage::updateMods()
void ModFolderPage::updateMods(bool includeDeps)
{
if (m_instance->typeName() != "Minecraft")
return; // this is a null instance or a legacy instance
@ -214,6 +235,10 @@ void ModFolderPage::updateMods()
QMessageBox::critical(this, tr("Error"), tr("Please install a mod loader first!"));
return;
}
if (APPLICATION->settings()->get("ModMetadataDisabled").toBool()) {
QMessageBox::critical(this, tr("Error"), tr("Mod updates are unavailable when metadata is disabled!"));
return;
}
auto selection = m_filterModel->mapSelectionToSource(ui->treeView->selectionModel()->selection()).indexes();
auto mods_list = m_model->selectedMods(selection);
@ -221,7 +246,7 @@ void ModFolderPage::updateMods()
if (use_all)
mods_list = m_model->allMods();
ModUpdateDialog update_dialog(this, m_instance, m_model, mods_list);
ModUpdateDialog update_dialog(this, m_instance, m_model, mods_list, includeDeps);
update_dialog.checkCandidates();
if (update_dialog.aborted()) {

View File

@ -64,7 +64,7 @@ class ModFolderPage : public ExternalResourcesPage {
void deleteModMetadata();
void installMods();
void updateMods();
void updateMods(bool includeDeps = false);
void visitModPages();
protected:

View File

@ -68,8 +68,8 @@
#include <FileSystem.h>
#include "RWStorage.h"
typedef RWStorage<QString, QIcon> SharedIconCache;
typedef std::shared_ptr<SharedIconCache> SharedIconCachePtr;
using SharedIconCache = RWStorage<QString, QIcon>;
using SharedIconCachePtr = std::shared_ptr<SharedIconCache>;
class ThumbnailingResult : public QObject {
Q_OBJECT
@ -383,20 +383,31 @@ void ScreenshotsPage::on_actionUpload_triggered()
QList<ScreenShot::Ptr> uploaded;
auto job = NetJob::Ptr(new NetJob("Screenshot Upload", APPLICATION->network()));
ProgressDialog dialog(this);
dialog.setSkipButton(true, tr("Abort"));
if (selection.size() < 2) {
auto item = selection.at(0);
auto info = m_model->fileInfo(item);
auto screenshot = std::make_shared<ScreenShot>(info);
job->addNetAction(ImgurUpload::make(screenshot));
m_uploadActive = true;
ProgressDialog dialog(this);
connect(job.get(), &Task::failed, [this](QString reason) {
CustomMessageBox::selectable(this, tr("Failed to upload screenshots!"), reason, QMessageBox::Critical)->show();
});
connect(job.get(), &Task::aborted, [this] {
CustomMessageBox::selectable(this, tr("Screenshots upload aborted"), tr("The task has been aborted by the user."),
QMessageBox::Information)
->show();
});
if (dialog.execWithTask(job.get()) != QDialog::Accepted) {
CustomMessageBox::selectable(this, tr("Failed to upload screenshots!"), tr("Unknown error"), QMessageBox::Warning)->exec();
} else {
m_uploadActive = true;
if (dialog.execWithTask(job.get()) == QDialog::Accepted) {
auto link = screenshot->m_url;
QClipboard* clipboard = QApplication::clipboard();
qDebug() << "ImgurUpload link" << link;
clipboard->setText(link);
CustomMessageBox::selectable(
this, tr("Upload finished"),
@ -417,22 +428,36 @@ void ScreenshotsPage::on_actionUpload_triggered()
}
SequentialTask task;
auto albumTask = NetJob::Ptr(new NetJob("Imgur Album Creation", APPLICATION->network()));
auto imgurAlbum = ImgurAlbumCreation::make(uploaded);
auto imgurResult = std::make_shared<ImgurAlbumCreation::Result>();
auto imgurAlbum = ImgurAlbumCreation::make(imgurResult, uploaded);
albumTask->addNetAction(imgurAlbum);
task.addTask(job);
task.addTask(albumTask);
m_uploadActive = true;
ProgressDialog prog(this);
if (prog.execWithTask(&task) != QDialog::Accepted) {
CustomMessageBox::selectable(this, tr("Failed to upload screenshots!"), tr("Unknown error"), QMessageBox::Warning)->exec();
} else {
auto link = QString("https://imgur.com/a/%1").arg(imgurAlbum->id());
QClipboard* clipboard = QApplication::clipboard();
clipboard->setText(link);
CustomMessageBox::selectable(this, tr("Upload finished"),
tr("The <a href=\"%1\">link to the uploaded album</a> has been placed in your clipboard.").arg(link),
connect(&task, &Task::failed, [this](QString reason) {
CustomMessageBox::selectable(this, tr("Failed to upload screenshots!"), reason, QMessageBox::Critical)->show();
});
connect(&task, &Task::aborted, [this] {
CustomMessageBox::selectable(this, tr("Screenshots upload aborted"), tr("The task has been aborted by the user."),
QMessageBox::Information)
->exec();
->show();
});
m_uploadActive = true;
if (dialog.execWithTask(&task) == QDialog::Accepted) {
if (imgurResult->id.isEmpty()) {
CustomMessageBox::selectable(this, tr("Failed to upload screenshots!"), tr("Unknown error"), QMessageBox::Warning)->exec();
} else {
auto link = QString("https://imgur.com/a/%1").arg(imgurResult->id);
qDebug() << "ImgurUpload link" << link;
QClipboard* clipboard = QApplication::clipboard();
clipboard->setText(link);
CustomMessageBox::selectable(
this, tr("Upload finished"),
tr("The <a href=\"%1\">link to the uploaded album</a> has been placed in your clipboard.").arg(link),
QMessageBox::Information)
->exec();
}
}
m_uploadActive = false;
}

View File

@ -24,8 +24,8 @@
namespace Atl {
typedef QMap<QString, QIcon> LogoMap;
typedef std::function<void(QString)> LogoCallback;
using LogoMap = QMap<QString, QIcon>;
using LogoCallback = std::function<void(QString)>;
class ListModel : public QAbstractListModel {
Q_OBJECT

Some files were not shown because too many files have changed in this diff Show More