KXmlGui

kshortcutschemeshelper.cpp
1 /*
2  This file is part of the KDE libraries
3  SPDX-FileCopyrightText: 2008 Alexander Dymo <[email protected]>
4 
5  SPDX-License-Identifier: LGPL-2.0-or-later
6 */
7 
8 #include "kshortcutschemeshelper_p.h"
9 
10 #include <QAction>
11 #include <QCoreApplication>
12 #include <QFile>
13 #include <QTextStream>
14 #include <QDomDocument>
15 #include <QStandardPaths>
16 
17 #include <QDir>
18 #include <kconfiggroup.h>
19 #include <ksharedconfig.h>
20 
21 #include "kactioncollection.h"
22 #include "kxmlguiclient.h"
23 #include "debug.h"
24 
25 bool KShortcutSchemesHelper::saveShortcutScheme(const QList<KActionCollection *> &collections,
26  const QString &schemeName)
27 {
28  // Every action collection is associated with a KXMLGUIClient
29  // (at least if it was added by KXMLGUIFactory::configureShortcuts)
30 
31  // Some GUI clients have the same name (e.g. the child client for a mainwindow
32  // holding the actions for hiding/showing toolbars), so we need to save them
33  // together, otherwise they will overwrite each other's file on disk.
34 
35  // For cases like kdevelop (many guiclients not reused in other apps) it's simpler
36  // to even save all shortcuts to a single shortcuts file -> set the boolean below to true
37  // to create an all-in-one scheme.
38  // Maybe we need a checkbox for this? Or an env var for contributors to set, rather? End users don't care.
39  const bool saveToApplicationFile = false;
40 
41  QMultiMap<QString, KActionCollection *> collectionsByClientName;
42  for (KActionCollection *coll : collections) {
43  const KXMLGUIClient *client = coll->parentGUIClient();
44  if (client) {
45  const QString key = saveToApplicationFile ? QCoreApplication::applicationName() : client->componentName();
46  collectionsByClientName.insert(key, coll);
47  }
48  }
49  const auto componentNames = collectionsByClientName.uniqueKeys();
50  for (const QString &componentName : componentNames) {
51 
52  qCDebug(DEBUG_KXMLGUI) << "Considering component" << componentName;
53  QDomDocument doc;
54  QDomElement docElem = doc.createElement(QStringLiteral("gui"));
55  docElem.setAttribute(QStringLiteral("version"), QStringLiteral("1"));
56  docElem.setAttribute(QStringLiteral("name"), componentName);
57  doc.appendChild(docElem);
58  QDomElement elem = doc.createElement(QStringLiteral("ActionProperties"));
59  docElem.appendChild(elem);
60 
61  const auto componentCollections = collectionsByClientName.values(componentName);
62  for (KActionCollection *collection : componentCollections) {
63  qCDebug(DEBUG_KXMLGUI) << "Saving shortcut scheme for action collection with" << collection->actions().count() << "actions";
64 
65  const auto collectionActions = collection->actions();
66  for (QAction *action : collectionActions) {
67  if (!action) {
68  continue;
69  }
70 
71  const QString actionName = action->objectName();
72  const QString shortcut = QKeySequence::listToString(action->shortcuts());
73  //qCDebug(DEBUG_KXMLGUI) << "action" << actionName << "has shortcut" << shortcut;
74  if (!shortcut.isEmpty()) {
75  QDomElement act_elem = doc.createElement(QStringLiteral("Action"));
76  act_elem.setAttribute(QStringLiteral("name"), actionName);
77  act_elem.setAttribute(QStringLiteral("shortcut"), shortcut);
78  elem.appendChild(act_elem);
79  }
80  }
81  }
82 
83 
84  const QString schemeFileName = writableShortcutSchemeFileName(componentName, schemeName);
85  if (elem.childNodes().isEmpty()) {
86  QFile::remove(schemeFileName);
87  } else {
88  qCDebug(DEBUG_KXMLGUI) << "saving to" << schemeFileName;
89  QDir().mkpath(QFileInfo(schemeFileName).absolutePath());
90  QFile schemeFile(schemeFileName);
91  if (!schemeFile.open(QFile::WriteOnly | QFile::Truncate)) {
92  qCDebug(DEBUG_KXMLGUI) << "COULD NOT WRITE" << schemeFileName;
93  return false;
94  }
95 
96  QTextStream out(&schemeFile);
97  out << doc.toString(2);
98  }
99  }
100  return true;
101 }
102 
103 QString KShortcutSchemesHelper::currentShortcutSchemeName()
104 {
105  return KSharedConfig::openConfig()->group("Shortcut Schemes").readEntry("Current Scheme", "Default");
106 }
107 
108 QString KShortcutSchemesHelper::writableShortcutSchemeFileName(const QString &componentName, const QString &schemeName)
109 {
111  componentName + QLatin1String("/shortcuts/") +
112  schemeName;
113 }
114 
115 QString KShortcutSchemesHelper::writableApplicationShortcutSchemeFileName(const QString &schemeName)
116 {
119  schemeName;
120 }
121 
122 QString KShortcutSchemesHelper::shortcutSchemeFileName(const QString &componentName, const QString &schemeName)
123 {
125  componentName + QLatin1String("/shortcuts/") +
126  schemeName);
127 }
128 
129 QString KShortcutSchemesHelper::applicationShortcutSchemeFileName(const QString &schemeName)
130 {
133  schemeName);
134 }
A container for a set of QAction objects.
QString writableLocation(QStandardPaths::StandardLocation type)
A KXMLGUIClient can be used with KXMLGUIFactory to create a GUI from actions and an XML document...
Definition: kxmlguiclient.h:38
QDomNode appendChild(const QDomNode &newChild)
bool remove()
QString listToString(const QList< QKeySequence > &list, QKeySequence::SequenceFormat format)
QString toString(int indent) const const
QDomNodeList childNodes() const const
QList< Key > uniqueKeys() const const
bool isEmpty() const const
int count(const T &value) const const
void setAttribute(const QString &name, const QString &value)
bool isEmpty() const const
typename QMap< Key, T >::iterator insert(const Key &key, const T &value)
static KSharedConfig::Ptr openConfig(const QString &fileName=QString(), OpenFlags mode=FullConfig, QStandardPaths::StandardLocation type=QStandardPaths::GenericConfigLocation)
QList< QString > componentNames()
const QList< QKeySequence > & shortcut(StandardShortcut id)
QDomElement createElement(const QString &tagName)
bool mkpath(const QString &dirPath) const const
QString applicationName()
QString locate(QStandardPaths::StandardLocation type, const QString &fileName, QStandardPaths::LocateOptions options)
QList< T > values(const Key &key) const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Wed Aug 12 2020 22:50:46 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.