File indexing completed on 2024-05-12 05:35:43
0001 /* 0002 SPDX-FileCopyrightText: 2010 Andriy Rysin <rysin@kde.org> 0003 SPDX-FileCopyrightText: 2021 Cyril Rossi <cyril.rossi@enioka.com> 0004 0005 SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 #include "keyboard_config.h" 0009 #include "debug.h" 0010 0011 #include <KConfigGroup> 0012 #include <KSharedConfig> 0013 0014 static const QStringList SWITCHING_POLICIES = {QStringLiteral("Global"), QStringLiteral("Desktop"), QStringLiteral("WinClass"), QStringLiteral("Window")}; 0015 const int KeyboardConfig::NO_LOOPING = -1; 0016 0017 static KeyboardConfig::SwitchingPolicy findStringIndex(const QString &toFind, KeyboardConfig::SwitchingPolicy defaultPolicy) 0018 { 0019 const int index = SWITCHING_POLICIES.indexOf(toFind); 0020 if (index < 0) { 0021 return defaultPolicy; 0022 } 0023 return static_cast<KeyboardConfig::SwitchingPolicy>(index); 0024 } 0025 0026 KeyboardConfig::KeyboardConfig(QObject *parent) 0027 : KeyboardSettingsBase(parent) 0028 , m_referenceLayoutLoopCount(mLayoutLoopCount) 0029 { 0030 layouts.clear(); 0031 } 0032 0033 KeyboardConfig::SwitchingPolicy KeyboardConfig::switchingPolicy() const 0034 { 0035 return findStringIndex(switchMode(), SWITCH_POLICY_GLOBAL); 0036 } 0037 0038 void KeyboardConfig::setSwitchingPolicy(KeyboardConfig::SwitchingPolicy switchingPolicy) 0039 { 0040 setSwitchMode(SWITCHING_POLICIES.at(switchingPolicy)); 0041 } 0042 0043 KeyboardConfig::SwitchingPolicy KeyboardConfig::defaultSwitchingPolicyValue() const 0044 { 0045 return findStringIndex(defaultSwitchModeValue(), SWITCH_POLICY_GLOBAL); 0046 } 0047 0048 bool KeyboardConfig::layoutsSaveNeeded() const 0049 { 0050 if (layouts.size() != m_referenceLayouts.size()) { 0051 return true; 0052 } 0053 if (mLayoutLoopCount != m_referenceLayoutLoopCount) { 0054 return true; 0055 } 0056 0057 // Due to layoutUnit operator==() that does not test all properties. 0058 // Do not compare shortcuts, they are automatically applied 0059 bool isSaveNeeded = false; 0060 for (int i = 0; i < layouts.size(); ++i) { 0061 isSaveNeeded |= layouts.at(i).getDisplayName() != m_referenceLayouts.at(i).getDisplayName(); 0062 isSaveNeeded |= layouts.at(i).layout() != m_referenceLayouts.at(i).layout(); 0063 isSaveNeeded |= layouts.at(i).variant() != m_referenceLayouts.at(i).variant(); 0064 if (isSaveNeeded) { 0065 return isSaveNeeded; 0066 } 0067 } 0068 return isSaveNeeded; 0069 } 0070 0071 QString KeyboardConfig::getSwitchingPolicyString(SwitchingPolicy switchingPolicy) 0072 { 0073 return SWITCHING_POLICIES.at(switchingPolicy); 0074 } 0075 0076 void KeyboardConfig::setDefaults() 0077 { 0078 layouts.clear(); 0079 } 0080 0081 void KeyboardConfig::load() 0082 { 0083 KeyboardSettingsBase::load(); 0084 0085 const QStringList layoutStrings = layoutList(); 0086 const QStringList variants = variantList(); 0087 const QStringList names = displayNames(); 0088 0089 layouts.clear(); 0090 for (int i = 0; i < layoutStrings.size(); ++i) { 0091 if (i < variants.size()) { 0092 layouts.append({layoutStrings[i], variants[i]}); 0093 } else { 0094 layouts.append(LayoutUnit(layoutStrings[i])); 0095 } 0096 0097 if (i < names.size() && !names[i].isEmpty() && names[i] != layouts[i].layout()) { 0098 layouts[i].setDisplayName(names[i]); 0099 } 0100 } 0101 0102 // layouts' shortcuts are retrieved from GlobalShortcuts in KCMKeyboardWidget 0103 m_referenceLayouts = layouts; 0104 m_referenceLayoutLoopCount = mLayoutLoopCount; 0105 0106 qCDebug(KCM_KEYBOARD) << "configuring layouts" << configureLayouts() << "configuring options" << resetOldXkbOptions(); 0107 } 0108 0109 void KeyboardConfig::save() 0110 { 0111 m_referenceLayouts = layouts; 0112 m_referenceLayoutLoopCount = mLayoutLoopCount; 0113 0114 QStringList layoutList; 0115 QStringList variants; 0116 QStringList displayNames; 0117 for (const LayoutUnit &layoutUnit : std::as_const(layouts)) { 0118 layoutList.append(layoutUnit.layout()); 0119 variants.append(layoutUnit.variant()); 0120 displayNames.append(layoutUnit.getRawDisplayName()); 0121 } 0122 0123 // QStringLists with a single empty string are serialized as "\\0", avoid that 0124 // by saving them as an empty list instead. This way it can be passed as-is to 0125 // libxkbcommon/setxkbmap. Before KConfigXT it used QStringList::join(","). 0126 if (variants.size() == 1 && variants.constFirst().isEmpty()) { 0127 variants.clear(); 0128 } 0129 if (displayNames.size() == 1 && displayNames.constFirst().isEmpty()) { 0130 displayNames.clear(); 0131 } 0132 0133 setLayoutList(layoutList); 0134 setVariantList(variants); 0135 setDisplayNames(displayNames); 0136 0137 KeyboardSettingsBase::save(); 0138 } 0139 0140 QList<LayoutUnit> KeyboardConfig::getDefaultLayouts() const 0141 { 0142 QList<LayoutUnit> defaultLayoutList; 0143 int i = 0; 0144 for (const LayoutUnit &layoutUnit : std::as_const(layouts)) { 0145 defaultLayoutList.append(layoutUnit); 0146 if (layoutLoopCount() != KeyboardConfig::NO_LOOPING && i >= layoutLoopCount() - 1) { 0147 break; 0148 } 0149 i++; 0150 } 0151 return defaultLayoutList; 0152 } 0153 0154 QList<LayoutUnit> KeyboardConfig::getExtraLayouts() const 0155 { 0156 if (layoutLoopCount() == KeyboardConfig::NO_LOOPING) { 0157 return QList<LayoutUnit>(); 0158 } 0159 0160 return layouts.mid(layoutLoopCount(), layouts.size()); 0161 }