You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
137 lines
6.2 KiB
137 lines
6.2 KiB
/* |
|
SPDX-FileCopyrightText: 2021 Dan Leinir Turthra Jensen <admin@leinir.dk> |
|
|
|
SPDX-License-Identifier: LGPL-2.0-only |
|
*/ |
|
|
|
#include "cursorthemesettings.h" |
|
|
|
#include "../kcms-common_p.h" |
|
|
|
#include "xcursor/cursortheme.h" |
|
#include "xcursor/themeapplicator.h" |
|
#include "xcursor/thememodel.h" |
|
|
|
#include <KLocalizedString> |
|
|
|
#include <QApplication> |
|
#include <QCommandLineParser> |
|
#include <QDebug> |
|
#include <QFile> |
|
#include <QTimer> |
|
|
|
namespace { |
|
/** Apply a theme, log warnings |
|
* |
|
* Applies @p theme; if @p sizeSpecifier is an integer that is an available |
|
* size for the theme, use it rather than the theme's default size. |
|
* If @p sizeSpecifier is non-empty but doesn't name an integer that |
|
* is an available size, prints an error message to @p ts and uses the |
|
* theme's default size instead. |
|
*/ |
|
bool applyThemeAndSize(const CursorTheme* theme, const QString& sizeSpecifier, QTextStream& ts) |
|
{ |
|
auto chosenSize = theme->defaultCursorSize(); |
|
if (!sizeSpecifier.isEmpty()) { |
|
bool ok = false; |
|
int specificSize = sizeSpecifier.toInt(&ok); |
|
if (ok && theme->availableSizes().contains(specificSize)) { |
|
chosenSize = specificSize; |
|
} else { |
|
ts << i18n("The requested size '%1' is not available, using %2 instead.").arg(sizeSpecifier).arg(chosenSize) << Qt::endl; |
|
// Not an error condition |
|
} |
|
} |
|
return applyTheme(theme, chosenSize); |
|
} |
|
} |
|
|
|
int main(int argc, char **argv) |
|
{ |
|
// This is a CLI application, but we require at least a QGuiApplication for things |
|
// in Plasma::Theme, so let's just roll with one of these |
|
QApplication app(argc, argv); |
|
QCoreApplication::setApplicationName(QStringLiteral("plasma-apply-cursortheme")); |
|
QCoreApplication::setApplicationVersion(QStringLiteral("1.0")); |
|
QCoreApplication::setOrganizationDomain(QStringLiteral("kde.org")); |
|
KLocalizedString::setApplicationDomain("plasma-apply-cursortheme"); |
|
|
|
QCommandLineParser *parser = new QCommandLineParser; |
|
parser->addHelpOption(); |
|
parser->setApplicationDescription( |
|
i18n("This tool allows you to set the mouse cursor theme for the current Plasma session, without accidentally setting it to one that is either not " |
|
"available, or which is already set.")); |
|
parser->addPositionalArgument( |
|
QStringLiteral("cursortheme"), |
|
i18n("The name of the cursor theme you wish to set for your current Plasma session (passing a full path will only use the last part of the path)")); |
|
parser->addOption(QCommandLineOption(QStringLiteral("list-themes"), i18n("Show all the themes available on the system (and which is the current theme)"))); |
|
parser->addOption(QCommandLineOption(QStringLiteral("size"), i18n("Use a specific size, rather than the theme default size"), QStringLiteral("size"))); |
|
parser->process(app); |
|
|
|
int errorCode{0}; |
|
CursorThemeSettings *settings = new CursorThemeSettings(&app); |
|
QTextStream ts(stdout); |
|
CursorThemeModel *model = new CursorThemeModel(&app); |
|
if (!parser->positionalArguments().isEmpty()) { |
|
QString requestedTheme{parser->positionalArguments().first()}; |
|
const QString dirSplit{"/"}; |
|
if (requestedTheme.contains(dirSplit)) { |
|
QStringList splitTheme = requestedTheme.split(dirSplit, Qt::SkipEmptyParts); |
|
// Cursor themes installed through KNewStuff will commonly be given an installed files entry |
|
// which has the main directory name and an asterisk to say the cursors are all in that directory, |
|
// and since one of the main purposes of this tool is to allow adopting things from a KNS dialog, |
|
// we handle that little weirdness here. |
|
splitTheme.removeAll(QStringLiteral("*")); |
|
requestedTheme = splitTheme.last(); |
|
} |
|
|
|
if (settings->cursorTheme() == requestedTheme) { |
|
ts << i18n("The requested theme \"%1\" is already set as the theme for the current Plasma session.", requestedTheme) << Qt::endl; |
|
// This is not an error condition, no reason to set an error code |
|
} else { |
|
auto results = model->findIndex(requestedTheme); |
|
QModelIndex selected = model->index(results.row(), 0); |
|
const CursorTheme *theme = selected.isValid() ? model->theme(selected) : nullptr; |
|
|
|
if (theme) { |
|
settings->setCursorTheme(theme->name()); |
|
if (settings->save() && applyThemeAndSize(theme, parser->value("size"), ts)) { |
|
notifyKcmChange(GlobalChangeType::CursorChanged); |
|
ts << i18n("Successfully applied the mouse cursor theme %1 to your current Plasma session", theme->title()) << Qt::endl; |
|
} else { |
|
ts << i18n("You have to restart the Plasma session for your newly applied mouse cursor theme to display correctly.") << Qt::endl; |
|
// A bit of an odd one, more a warning than an error, but this means we can forward it |
|
errorCode = -1; |
|
} |
|
} else { |
|
QStringList availableThemes; |
|
for (int i = 0; i < model->rowCount(); ++i) { |
|
const CursorTheme *theme = model->theme(model->index(i, 0)); |
|
availableThemes << theme->name(); |
|
} |
|
ts << i18n("Could not find theme \"%1\". The theme should be one of the following options: %2", |
|
requestedTheme, |
|
availableThemes.join(QLatin1String{", "})) |
|
<< Qt::endl; |
|
errorCode = -1; |
|
} |
|
} |
|
} else if (parser->isSet(QStringLiteral("list-themes"))) { |
|
ts << i18n("You have the following mouse cursor themes on your system:") << Qt::endl; |
|
for (int i = 0; i < model->rowCount(); ++i) { |
|
const CursorTheme *theme = model->theme(model->index(i, 0)); |
|
ts << QString(" * %1 [%2]").arg(theme->title()).arg(theme->name()); |
|
if (settings->cursorTheme() == theme->name()) { |
|
ts << QChar(' ') << i18n("(Current theme for this Plasma session)"); |
|
} |
|
ts << Qt::endl; |
|
} |
|
} else { |
|
parser->showHelp(); |
|
} |
|
QTimer::singleShot(0, &app, [&app, &errorCode]() { |
|
app.exit(errorCode); |
|
}); |
|
|
|
return app.exec(); |
|
}
|
|
|