File indexing completed on 2024-04-21 16:17:13

0001 /*
0002 *  Copyright 2019  Michail Vourlakos <mvourlakos@gmail.com>
0003 *
0004 *  This file is part of Latte-Dock
0005 *
0006 *  Latte-Dock is free software; you can redistribute it and/or
0007 *  modify it under the terms of the GNU General Public License as
0008 *  published by the Free Software Foundation; either version 2 of
0009 *  the License, or (at your option) any later version.
0010 *
0011 *  Latte-Dock is distributed in the hope that it will be useful,
0012 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
0013 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0014 *  GNU General Public License for more details.
0015 *
0016 *  You should have received a copy of the GNU General Public License
0017 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
0018 */
0019 
0020 // local
0021 #include "shortcutstracker.h"
0022 
0023 // Qt
0024 #include <QAction>
0025 #include <QDir>
0026 #include <QDebug>
0027 
0028 // KDE
0029 #include <KConfigGroup>
0030 #include <KDirWatch>
0031 #include <KGlobalAccel>
0032 
0033 
0034 #define GLOBALSHORTCUTSCONFIG "kglobalshortcutsrc"
0035 #define APPLETSHORTCUTKEY "activate widget "
0036 
0037 namespace Latte {
0038 namespace ShortcutsPart {
0039 
0040 ShortcutsTracker::ShortcutsTracker(QObject *parent)
0041     : QObject(parent)
0042 {
0043     //! load global shortcuts badges at startup
0044     initGlobalShortcutsWatcher();
0045     parseGlobalShortcuts();
0046     clearAllAppletShortcuts();
0047 }
0048 
0049 ShortcutsTracker::~ShortcutsTracker()
0050 {
0051 }
0052 
0053 void ShortcutsTracker::initGlobalShortcutsWatcher()
0054 {
0055     for (int i=1; i<=19; ++i) {
0056         m_badgesForActivate << QString();
0057     }
0058 
0059     const QString globalShortcutsFilePath = QDir::homePath() + "/.config/" + GLOBALSHORTCUTSCONFIG;
0060     m_shortcutsConfigPtr = KSharedConfig::openConfig(globalShortcutsFilePath);
0061 
0062     KDirWatch::self()->addFile(globalShortcutsFilePath);
0063 
0064     connect(KDirWatch::self(), &KDirWatch::dirty, this, &ShortcutsTracker::shortcutsFileChanged, Qt::QueuedConnection);
0065     connect(KDirWatch::self(), &KDirWatch::created, this, &ShortcutsTracker::shortcutsFileChanged, Qt::QueuedConnection);
0066 }
0067 
0068 bool ShortcutsTracker::basedOnPositionEnabled() const
0069 {
0070     return m_basedOnPositionEnabled;
0071 }
0072 
0073 QStringList ShortcutsTracker::badgesForActivate() const
0074 {
0075     return m_badgesForActivate;
0076 }
0077 
0078 void ShortcutsTracker::shortcutsFileChanged(const QString &file)
0079 {
0080     if (!file.endsWith(GLOBALSHORTCUTSCONFIG)) {
0081         return;
0082     }
0083 
0084     m_shortcutsConfigPtr->reparseConfiguration();
0085     parseGlobalShortcuts();
0086 }
0087 
0088 QList<int> ShortcutsTracker::appletsWithPlasmaShortcuts()
0089 {
0090     return m_appletShortcuts.keys();
0091 }
0092 
0093 QString ShortcutsTracker::appletShortcutBadge(int appletId)
0094 {
0095     if (m_appletShortcuts.contains(appletId)) {
0096         return m_appletShortcuts[appletId];
0097     }
0098 
0099     return QString();
0100 }
0101 
0102 QString ShortcutsTracker::shortcutToBadge(QStringList shortcutRecords)
0103 {
0104     QString badge;
0105 
0106     if (shortcutRecords.count()>0 && shortcutRecords[0] != "none") {
0107         QStringList modifiers = shortcutRecords[0].split("+");
0108 
0109         if (modifiers.count() >= 1) {
0110             badge = modifiers[modifiers.count() - 1];
0111 
0112             //! when shortcut follows Meta+"Character" scheme
0113             if (modifiers.count() == 2 && modifiers[0] == "Meta") {
0114                 badge = badge.toLower();
0115             } else {
0116                 badge = badge.toUpper();
0117             }
0118         }
0119     }
0120 
0121     return badge;
0122 }
0123 
0124 void ShortcutsTracker::parseGlobalShortcuts()
0125 {
0126     KConfigGroup latteGroup = KConfigGroup(m_shortcutsConfigPtr, "lattedock");
0127 
0128     //! make sure that latte dock records in global shortcuts where found correctly
0129     bool recordExists{true};
0130 
0131     if (!latteGroup.exists()) {
0132         recordExists = false;
0133     }
0134 
0135     if (recordExists) {
0136         for (int i = 1; i <= 19; ++i) {
0137             QString entry = "activate entry " + QString::number(i);
0138 
0139             if (!latteGroup.hasKey(entry)) {
0140                 recordExists = false;
0141                 break;
0142             }
0143         }
0144     }
0145 
0146     if (recordExists) {
0147         m_badgesForActivate.clear();
0148         m_appletShortcuts.clear();
0149 
0150         for (int i = 1; i <= 19; ++i) {
0151             QString entry = "activate entry " + QString::number(i);
0152             QStringList records = latteGroup.readEntry(entry, QStringList());
0153 
0154             m_badgesForActivate << shortcutToBadge(records);
0155         }
0156 
0157         m_basedOnPositionEnabled = (!m_badgesForActivate[0].isEmpty() && !m_badgesForActivate[1].isEmpty());
0158 
0159         for(auto &key : latteGroup.keyList()) {
0160             if (key.startsWith(APPLETSHORTCUTKEY)) {
0161                 QStringList records = latteGroup.readEntry(key, QStringList());
0162                 int appletId = key.remove(APPLETSHORTCUTKEY).toInt();
0163 
0164                 m_appletShortcuts[appletId] = shortcutToBadge(records);
0165             }
0166         }
0167 
0168         qDebug() << "badges updated to :: " << m_badgesForActivate;
0169         qDebug() << "applet shortcuts updated to :: " << m_appletShortcuts;
0170 
0171         emit badgesForActivateChanged();
0172     }
0173 }
0174 
0175 void ShortcutsTracker::clearAllAppletShortcuts()
0176 {
0177     KConfigGroup latteGroup = KConfigGroup(m_shortcutsConfigPtr, "lattedock");
0178 
0179     for(const auto &key : latteGroup.keyList()) {
0180         if (key.startsWith(APPLETSHORTCUTKEY)) {
0181             QAction *appletAction = new QAction(this);
0182 
0183             appletAction->setText(QString("Activate ") + key);
0184             appletAction->setObjectName(key);
0185             appletAction->setShortcut(QKeySequence());
0186             KGlobalAccel::setGlobalShortcut(appletAction, QKeySequence());
0187             KGlobalAccel::self()->removeAllShortcuts(appletAction);
0188 
0189             appletAction->deleteLater();
0190         }
0191     }
0192 }
0193 
0194 
0195 }
0196 }