/* SPDX-FileCopyrightText: 2010 Andriy Rysin SPDX-FileCopyrightText: 2021 Cyril Rossi SPDX-License-Identifier: GPL-2.0-or-later */ #include "kcm_keyboard.h" #include #include #include #include "bindings.h" #include "keyboard_config.h" #include "keyboard_dbus.h" #include "keyboardmiscsettings.h" #include "keyboardmodel.h" #include "keyboardsettings.h" #include "keyboardsettingsdata.h" #include "layoutmodel.h" #include "shortcuthelper.h" #include "tastenbrett.h" #include "userlayoutmodel.h" #include "workspace_options.h" #include "x11_helper.h" #include "xkboptionsmodel.h" #include "debug.h" KCMKeyboard::KCMKeyboard(QObject *parent, const KPluginMetaData &data) : KQuickManagedConfigModule(parent, data) , m_data(new KeyboardSettingsData(this)) , m_config(new KeyboardConfig(m_data->keyboardSettings(), this)) , m_layoutModel(new LayoutModel(this)) , m_userLayoutModel(new UserLayoutModel(m_config, this)) , m_keyboardModel(new KeyboardModel(this)) , m_shortcutHelper(new ShortcutHelper(this)) , m_xkbOptionsModel(new XkbOptionsModel(this)) { const auto uri = "org.kde.plasma.private.kcm_keyboard"; qmlRegisterAnonymousType(uri, 1); qmlRegisterAnonymousType(uri, 1); qmlRegisterAnonymousType(uri, 1); qmlRegisterUncreatableMetaObject(NumLockState::staticMetaObject, uri, 1, 0, "NumLockState", QString()); connect(m_data->keyboardSettings(), &KeyboardSettings::configureLayoutsChanged, this, [this]() -> void { if (m_data->keyboardSettings()->configureLayouts()) { const QList layouts = X11Helper::getLayoutsList(); for (const auto &layoutUnit : layouts) { m_config->layouts().append(layoutUnit); } m_userLayoutModel->reset(); } else { m_userLayoutModel->clear(); } }); connect(m_data->keyboardSettings(), &KeyboardSettings::resetOldXkbOptionsChanged, this, [this]() -> void { if (m_data->keyboardSettings()->resetOldXkbOptions()) { m_xkbOptionsModel->populateWithCurrentXkbOptions(); m_data->keyboardSettings()->setXkbOptions(m_xkbOptionsModel->xkbOptions()); } }); connect(m_userLayoutModel, &UserLayoutModel::modelReset, this, &KCMKeyboard::resetShortcuts); connect(m_userLayoutModel, &UserLayoutModel::rowsInserted, this, &KCMKeyboard::resetShortcuts); connect(m_userLayoutModel, &UserLayoutModel::rowsRemoved, this, &KCMKeyboard::resetShortcuts); connect(m_userLayoutModel, &UserLayoutModel::dataChanged, this, &KCMKeyboard::resetShortcuts); connect(m_userLayoutModel, &UserLayoutModel::rowsMoved, this, &KCMKeyboard::settingsChanged); connect(m_shortcutHelper, &ShortcutHelper::alternativeShortcutChanged, this, &KCMKeyboard::settingsChanged); connect(m_shortcutHelper, &ShortcutHelper::lastUsedShortcutChanged, this, &KCMKeyboard::settingsChanged); connect(m_xkbOptionsModel, &XkbOptionsModel::dataChanged, this, &KCMKeyboard::settingsChanged); connect(m_xkbOptionsModel, &XkbOptionsModel::modelReset, this, &KCMKeyboard::settingsChanged); setButtons(Help | Default | Apply); } KCMKeyboard::~KCMKeyboard() { } WorkspaceOptions *KCMKeyboard::workspaceOptions() const { return m_data->workspaceOptions(); } KeyboardMiscSettings *KCMKeyboard::miscSettings() const { return m_data->keyboardMiscSettings(); } KeyboardSettings *KCMKeyboard::keyboardSettings() const { return m_data->keyboardSettings(); } LayoutModel *KCMKeyboard::layouts() const { return m_layoutModel; } UserLayoutModel *KCMKeyboard::userLayoutModel() const { return m_userLayoutModel; } KeyboardModel *KCMKeyboard::keyboards() const { return m_keyboardModel; } ShortcutHelper *KCMKeyboard::shortcutHelper() const { return m_shortcutHelper; } XkbOptionsModel *KCMKeyboard::xkbOptionsModel() const { return m_xkbOptionsModel; } int KCMKeyboard::maxGroupCount() const { return X11Helper::MAX_GROUP_COUNT; } bool KCMKeyboard::hasAccentSupport() { static bool isPlasmaIM = (qgetenv("QT_IM_MODULE") == "plasmaim"); return isPlasmaIM; } void KCMKeyboard::requestPreview(const QString &model, const QString &layout, const QString &variant, const QString &title) { Tastenbrett::launch(model, layout, variant, m_xkbOptionsModel->xkbOptions().join(QLatin1Char(',')), title); } void KCMKeyboard::defaults() { KQuickManagedConfigModule::defaults(); m_shortcutHelper->defaults(); m_xkbOptionsModel->setXkbOptions(m_data->keyboardSettings()->defaultXkbOptionsValue()); m_config->defaults(); m_userLayoutModel->reset(); } void KCMKeyboard::load() { KQuickManagedConfigModule::load(); m_shortcutHelper->load(); m_xkbOptionsModel->setXkbOptions(m_data->keyboardSettings()->xkbOptions()); m_config->load(); m_shortcutHelper->actionColletion()->loadLayoutShortcuts(m_config->layouts()); m_userLayoutModel->reset(); } void KCMKeyboard::save() { KQuickManagedConfigModule::save(); m_shortcutHelper->save(); QStringList options; if (m_data->keyboardSettings()->resetOldXkbOptions()) { options = m_xkbOptionsModel->xkbOptions(); // QStringLists with a single empty string are serialized as "\\0", avoid that // by saving them as an empty list instead. This way it can be passed as-is to // libxkbcommon/setxkbmap. Before KConfigXT it used QStringList::join(","). if (options.size() == 1 && options.constFirst().isEmpty()) { options.clear(); } } m_data->keyboardSettings()->setXkbOptions(options); m_data->keyboardSettings()->save(); m_shortcutHelper->actionColletion()->setLayoutShortcuts(m_config->layouts()); m_config->save(); m_userLayoutModel->reset(); QDBusMessage message = QDBusMessage::createSignal(KEYBOARD_DBUS_OBJECT_PATH, KEYBOARD_DBUS_SERVICE_NAME, KEYBOARD_DBUS_CONFIG_RELOAD_MESSAGE); QDBusConnection::sessionBus().send(message); } bool KCMKeyboard::isSaveNeeded() const { return m_data->workspaceOptions()->isSaveNeeded() || m_data->keyboardMiscSettings()->isSaveNeeded() || m_config->isSaveNeeded() || m_shortcutHelper->isSaveNeeded() || m_xkbOptionsModel->xkbOptions() != m_data->keyboardSettings()->xkbOptions(); } bool KCMKeyboard::isDefaults() const { return m_data->workspaceOptions()->isDefaults() || m_data->keyboardMiscSettings()->isDefaults() || m_config->isDefaults() || m_shortcutHelper->isSaveNeeded() || m_xkbOptionsModel->xkbOptions() == m_data->keyboardSettings()->xkbOptions(); } void KCMKeyboard::resetShortcuts() { settingsChanged(); m_shortcutHelper->actionColletion()->resetLayoutShortcuts(); m_shortcutHelper->actionColletion()->setLayoutShortcuts(m_config->layouts()); } #include "kcm_keyboard.moc" #include "moc_kcm_keyboard.cpp"