KXmlGui

kactioncollection.cpp
1/*
2 This file is part of the KDE libraries
3 SPDX-FileCopyrightText: 1999 Reginald Stadlbauer <reggie@kde.org>
4 SPDX-FileCopyrightText: 1999 Simon Hausmann <hausmann@kde.org>
5 SPDX-FileCopyrightText: 2000 Nicolas Hadacek <haadcek@kde.org>
6 SPDX-FileCopyrightText: 2000 Kurt Granroth <granroth@kde.org>
7 SPDX-FileCopyrightText: 2000 Michael Koch <koch@kde.org>
8 SPDX-FileCopyrightText: 2001 Holger Freyther <freyther@kde.org>
9 SPDX-FileCopyrightText: 2002 Ellis Whitehead <ellis@kde.org>
10 SPDX-FileCopyrightText: 2002 Joseph Wenninger <jowenn@kde.org>
11 SPDX-FileCopyrightText: 2005-2007 Hamish Rodda <rodda@kde.org>
12
13 SPDX-License-Identifier: LGPL-2.0-only
14*/
15
16#include "config-xmlgui.h"
17
18#include "kactioncollection.h"
19
20#include "debug.h"
21#include "kactioncategory.h"
22#include "kxmlguiclient.h"
23#include "kxmlguifactory.h"
24
25#include <KAuthorized>
26#include <KConfigGroup>
27#if HAVE_GLOBALACCEL
28#include <KGlobalAccel>
29#endif
30#include <KSharedConfig>
31
32#include <QDomDocument>
33#include <QGuiApplication>
34#include <QList>
35#include <QMap>
36#include <QMetaMethod>
37#include <QSet>
38
39#include <cstdio>
40
41static bool actionHasGlobalShortcut(const QAction *action)
42{
43#if HAVE_GLOBALACCEL
44 return KGlobalAccel::self()->hasShortcut(action);
45#else
46 return false;
47#endif
48}
49
50class KActionCollectionPrivate
51{
52public:
53 KActionCollectionPrivate(KActionCollection *qq)
54 : q(qq)
55 , configIsGlobal(false)
56 , connectTriggered(false)
57 , connectHovered(false)
58
59 {
60 }
61
62 void setComponentForAction(QAction *action)
63 {
64 const bool hasGlobalShortcut = actionHasGlobalShortcut(action);
65 if (!hasGlobalShortcut) {
66 action->setProperty("componentName", m_componentName);
67 action->setProperty("componentDisplayName", m_componentDisplayName);
68 }
69 }
70
71 static QList<KActionCollection *> s_allCollections;
72
73 void _k_associatedWidgetDestroyed(QObject *obj);
74 void _k_actionDestroyed(QObject *obj);
75
76 bool writeKXMLGUIConfigFile();
77
78 QString m_componentName;
79 QString m_componentDisplayName;
80
81 //! Remove a action from our internal bookkeeping. Returns a nullptr if the
82 //! action doesn't belong to us.
83 QAction *unlistAction(QAction *);
84
85 QMap<QString, QAction *> actionByName;
86 QList<QAction *> actions;
87
88 KActionCollection *q = nullptr;
89
90 const KXMLGUIClient *m_parentGUIClient = nullptr;
91
92 QString configGroup{QStringLiteral("Shortcuts")};
93 bool configIsGlobal : 1;
94
95 bool connectTriggered : 1;
96 bool connectHovered : 1;
97
98 QList<QWidget *> associatedWidgets;
99};
100
101QList<KActionCollection *> KActionCollectionPrivate::s_allCollections;
102
104 : QObject(parent)
105 , d(new KActionCollectionPrivate(this))
106{
107 KActionCollectionPrivate::s_allCollections.append(this);
108
109 setComponentName(cName);
110}
111
113 : QObject(nullptr)
114 , d(new KActionCollectionPrivate(this))
115{
116 KActionCollectionPrivate::s_allCollections.append(this);
117
118 d->m_parentGUIClient = parent;
119 d->m_componentName = parent->componentName();
120}
121
123{
124 KActionCollectionPrivate::s_allCollections.removeAll(this);
125}
126
128{
129 d->actionByName.clear();
130 qDeleteAll(d->actions);
131 d->actions.clear();
132}
133
135{
136 QAction *action = nullptr;
137
138 if (!name.isEmpty()) {
139 action = d->actionByName.value(name);
140 }
141
142 return action;
143}
144
146{
147 // ### investigate if any apps use this at all
148 return actions().value(index);
149}
150
152{
153 return d->actions.count();
154}
155
157{
158 return count() == 0;
159}
160
162{
163 for (QAction *a : std::as_const(d->actions)) {
164 if (actionHasGlobalShortcut(a)) {
165 // Its component name is part of an action's signature in the context of
166 // global shortcuts and the semantics of changing an existing action's
167 // signature are, as it seems, impossible to get right.
168 qCWarning(DEBUG_KXMLGUI) << "KActionCollection::setComponentName does not work on a KActionCollection containing actions with global shortcuts!"
169 << cName;
170 break;
171 }
172 }
173
174 if (!cName.isEmpty()) {
175 d->m_componentName = cName;
176 } else {
177 d->m_componentName = QCoreApplication::applicationName();
178 }
179}
180
182{
183 return d->m_componentName;
184}
185
187{
188 d->m_componentDisplayName = displayName;
189}
190
192{
193 if (!d->m_componentDisplayName.isEmpty()) {
194 return d->m_componentDisplayName;
195 }
198 }
200}
201
203{
204 return d->m_parentGUIClient;
205}
206
208{
209 return d->actions;
210}
211
213{
215 for (QAction *action : std::as_const(d->actions)) {
216 if (!action->actionGroup()) {
217 ret.append(action);
218 }
219 }
220 return ret;
221}
222
224{
226 for (QAction *action : std::as_const(d->actions)) {
227 if (action->actionGroup()) {
228 set.insert(action->actionGroup());
229 }
230 }
231 return set.values();
232}
233
235{
236 if (!action) {
237 return action;
238 }
239
241 QString indexName = name;
242
243 if (indexName.isEmpty()) {
244 // No name provided. Use the objectName.
245 indexName = objectName;
246
247 } else {
248 // A name was provided. Check against objectName.
249 if ((!objectName.isEmpty()) && (objectName != indexName)) {
250 // The user specified a new name and the action already has a
251 // different one. The objectName is used for saving shortcut
252 // settings to disk. Both for local and global shortcuts.
253 qCDebug(DEBUG_KXMLGUI) << "Registering action " << objectName << " under new name " << indexName;
254 // If there is a global shortcuts it's a very bad idea.
255#if HAVE_GLOBALACCEL
256 if (KGlobalAccel::self()->hasShortcut(action)) {
257 // In debug mode assert
258 Q_ASSERT(!KGlobalAccel::self()->hasShortcut(action));
259 // In release mode keep the old name
260 qCCritical(DEBUG_KXMLGUI) << "Changing action name from " << objectName << " to " << indexName
261 << "\nignored because of active global shortcut.";
262 indexName = objectName;
263 }
264#endif
265 }
266
267 // Set the new name
268 action->setObjectName(indexName);
269 }
270
271 // No name provided and the action had no name. Make one up. This will not
272 // work when trying to save shortcuts. Both local and global shortcuts.
273 if (indexName.isEmpty()) {
274 indexName = QString::asprintf("unnamed-%p", (void *)action);
275 action->setObjectName(indexName);
276 }
277
278 // From now on the objectName has to have a value. Else we cannot safely
279 // remove actions.
280 Q_ASSERT(!action->objectName().isEmpty());
281
282 // look if we already have THIS action under THIS name ;)
283 if (d->actionByName.value(indexName, nullptr) == action) {
284 // This is not a multi map!
285 Q_ASSERT(d->actionByName.count(indexName) == 1);
286 return action;
287 }
288
289 if (!KAuthorized::authorizeAction(indexName)) {
290 // Disable this action
291 action->setEnabled(false);
292 action->setVisible(false);
293 action->blockSignals(true);
294 }
295
296 // Check if we have another action under this name
297 if (QAction *oldAction = d->actionByName.value(indexName)) {
298 takeAction(oldAction);
299 }
300
301 // Check if we have this action under a different name.
302 // Not using takeAction because we don't want to remove it from categories,
303 // and because it has the new name already.
304 const int oldIndex = d->actions.indexOf(action);
305 if (oldIndex != -1) {
306 d->actionByName.remove(d->actionByName.key(action));
307 d->actions.removeAt(oldIndex);
308 }
309
310 // Add action to our lists.
311 d->actionByName.insert(indexName, action);
312 d->actions.append(action);
313
314 for (QWidget *widget : std::as_const(d->associatedWidgets)) {
315 widget->addAction(action);
316 }
317
318 connect(action, &QObject::destroyed, this, [this](QObject *obj) {
319 d->_k_actionDestroyed(obj);
320 });
321
322 d->setComponentForAction(action);
323
324 if (d->connectHovered) {
325 connect(action, &QAction::hovered, this, &KActionCollection::slotActionHovered);
326 }
327
328 if (d->connectTriggered) {
329 connect(action, &QAction::triggered, this, &KActionCollection::slotActionTriggered);
330 }
331
333 Q_EMIT changed();
334 return action;
335}
336
338{
339 for (QAction *action : actions) {
341 }
342}
343
345{
346 delete takeAction(action);
347}
348
350{
351 if (!d->unlistAction(action)) {
352 return nullptr;
353 }
354
355 // Remove the action from all widgets
356 for (QWidget *widget : std::as_const(d->associatedWidgets)) {
357 widget->removeAction(action);
358 }
359
360 action->disconnect(this);
361
362 Q_EMIT changed();
363 return action;
364}
365
366QAction *KActionCollection::addAction(KStandardAction::StandardAction actionType, const QObject *receiver, const char *member)
367{
368 QAction *action = KStandardAction::create(actionType, receiver, member, this);
369 return action;
370}
371
372QAction *KActionCollection::addAction(KStandardAction::StandardAction actionType, const QString &name, const QObject *receiver, const char *member)
373{
374 // pass 0 as parent, because if the parent is a KActionCollection KStandardAction::create automatically
375 // adds the action to it under the default name. We would trigger the
376 // warning about renaming the action then.
377 QAction *action = KStandardAction::create(actionType, receiver, member, nullptr);
378 // Give it a parent for gc.
379 action->setParent(this);
380 // Remove the name to get rid of the "rename action" warning above
381 action->setObjectName(name);
382 // And now add it with the desired name.
383 return addAction(name, action);
384}
385
386QAction *KActionCollection::addAction(const QString &name, const QObject *receiver, const char *member)
387{
388 QAction *a = new QAction(this);
389 if (receiver && member) {
390 connect(a, SIGNAL(triggered(bool)), receiver, member);
391 }
392 return addAction(name, a);
393}
394
396{
398 return shortcuts.isEmpty() ? QKeySequence() : shortcuts.first();
399}
400
405
410
412{
413 action->setShortcuts(shortcuts);
414 action->setProperty("defaultShortcuts", QVariant::fromValue(shortcuts));
415}
416
418{
419 // Considered as true by default
420 const QVariant value = action->property("isShortcutConfigurable");
421 return value.isValid() ? value.toBool() : true;
422}
423
425{
426 action->setProperty("isShortcutConfigurable", configurable);
427}
428
429QString KActionCollection::configGroup() const
430{
431 return d->configGroup;
432}
433
435{
436 d->configGroup = group;
437}
438
439bool KActionCollection::configIsGlobal() const
440{
441 return d->configIsGlobal;
442}
443
445{
446 d->configIsGlobal = global;
447}
448
450{
451#if HAVE_GLOBALACCEL
452 Q_ASSERT(config);
453 if (!config || !config->exists()) {
454 return;
455 }
456
457 for (QMap<QString, QAction *>::ConstIterator it = d->actionByName.constBegin(); it != d->actionByName.constEnd(); ++it) {
458 QAction *action = it.value();
459 if (!action) {
460 continue;
461 }
462
463 const QString &actionName = it.key();
464
466 QString entry = config->readEntry(actionName, QString());
467 if (!entry.isEmpty()) {
469 } else {
472 }
473 }
474 }
475#else
476 Q_UNUSED(config);
477#endif
478}
479
481{
482 KConfigGroup cg(KSharedConfig::openConfig(), configGroup());
483 if (!config) {
484 config = &cg;
485 }
486
487 if (!config->exists()) {
488 return;
489 }
490
491 for (QMap<QString, QAction *>::ConstIterator it = d->actionByName.constBegin(); it != d->actionByName.constEnd(); ++it) {
492 QAction *action = it.value();
493 if (!action) {
494 continue;
495 }
496
498 const QString &actionName = it.key();
499 QString entry = config->readEntry(actionName, QString());
500 if (!entry.isEmpty()) {
502 } else {
504 }
505 }
506 }
507
508 // qCDebug(DEBUG_KXMLGUI) << " done";
509}
510
512{
513#if HAVE_GLOBALACCEL
514 Q_ASSERT(config);
515 if (!config) {
516 return;
517 }
518
519 for (QMap<QString, QAction *>::ConstIterator it = d->actionByName.constBegin(); it != d->actionByName.constEnd(); ++it) {
520 QAction *action = it.value();
521 if (!action) {
522 continue;
523 }
524 const QString &actionName = it.key();
525
526 // If the action name starts with unnamed- spit out a warning. That name
527 // will change at will and will break loading writing
528 if (actionName.startsWith(QLatin1String("unnamed-"))) {
529 qCCritical(DEBUG_KXMLGUI) << "Skipped exporting Shortcut for action without name " << action->text() << "!";
530 continue;
531 }
532
534 bool bConfigHasAction = !config->readEntry(actionName, QString()).isEmpty();
536 // If we're using a global config or this setting
537 // differs from the default, then we want to write.
539 if (configIsGlobal()) {
540 flags |= KConfigGroup::Global;
541 }
542 if (writeAll || !bSameAsDefault) {
544 if (s.isEmpty()) {
545 s = QStringLiteral("none");
546 }
547 qCDebug(DEBUG_KXMLGUI) << "\twriting " << actionName << " = " << s;
548 config->writeEntry(actionName, s, flags);
549 }
550 // Otherwise, this key is the same as default
551 // but exists in config file. Remove it.
552 else if (bConfigHasAction) {
553 qCDebug(DEBUG_KXMLGUI) << "\tremoving " << actionName << " because == default";
554 config->deleteEntry(actionName, flags);
555 }
556 }
557 }
558
559 config->sync();
560#else
561 Q_UNUSED(config);
562 Q_UNUSED(writeAll);
563#endif
564}
565
566bool KActionCollectionPrivate::writeKXMLGUIConfigFile()
567{
568 const KXMLGUIClient *kxmlguiClient = q->parentGUIClient();
569 // return false if there is no KXMLGUIClient
570 if (!kxmlguiClient || kxmlguiClient->xmlFile().isEmpty()) {
571 return false;
572 }
573
574 qCDebug(DEBUG_KXMLGUI) << "xmlFile=" << kxmlguiClient->xmlFile();
575
576 QString attrShortcut = QStringLiteral("shortcut");
577
578 // Read XML file
579 QString sXml(KXMLGUIFactory::readConfigFile(kxmlguiClient->xmlFile(), q->componentName()));
580 QDomDocument doc;
581 doc.setContent(sXml);
582
583 // Process XML data
584
585 // Get hold of ActionProperties tag
587
588 // now, iterate through our actions
589 for (QMap<QString, QAction *>::ConstIterator it = actionByName.constBegin(); it != actionByName.constEnd(); ++it) {
590 QAction *action = it.value();
591 if (!action) {
592 continue;
593 }
594
595 const QString &actionName = it.key();
596
597 // If the action name starts with unnamed- spit out a warning and ignore
598 // it. That name will change at will and will break loading writing
599 if (actionName.startsWith(QLatin1String("unnamed-"))) {
600 qCCritical(DEBUG_KXMLGUI) << "Skipped writing shortcut for action " << actionName << "(" << action->text() << ")!";
601 continue;
602 }
603
604 bool bSameAsDefault = (action->shortcuts() == q->defaultShortcuts(action));
605 qCDebug(DEBUG_KXMLGUI) << "name = " << actionName << " shortcut = " << QKeySequence::listToString(action->shortcuts())
606#if HAVE_GLOBALACCEL
607 << " globalshortcut = " << QKeySequence::listToString(KGlobalAccel::self()->shortcut(action))
608#endif
609 << " def = " << QKeySequence::listToString(q->defaultShortcuts(action));
610
611 // now see if this element already exists
612 // and create it if necessary (unless bSameAsDefault)
613 QDomElement act_elem = KXMLGUIFactory::findActionByName(elem, actionName, !bSameAsDefault);
614 if (act_elem.isNull()) {
615 continue;
616 }
617
618 if (bSameAsDefault) {
619 act_elem.removeAttribute(attrShortcut);
620 // qCDebug(DEBUG_KXMLGUI) << "act_elem.attributes().count() = " << act_elem.attributes().count();
621 if (act_elem.attributes().count() == 1) {
622 elem.removeChild(act_elem);
623 }
624 } else {
625 act_elem.setAttribute(attrShortcut, QKeySequence::listToString(action->shortcuts()));
626 }
627 }
628
629 // Write back to XML file
630 KXMLGUIFactory::saveConfigFile(doc, kxmlguiClient->localXMLFile(), q->componentName());
631 // and since we just changed the xml file clear the dom we have in memory
632 // it'll be rebuilt if needed
633 const_cast<KXMLGUIClient *>(kxmlguiClient)->setXMLGUIBuildDocument({});
634 return true;
635}
636
637void KActionCollection::writeSettings(KConfigGroup *config, bool writeAll, QAction *oneAction) const
638{
639 // If the caller didn't provide a config group we try to save the KXMLGUI
640 // Configuration file. If that succeeds we are finished.
641 if (config == nullptr && d->writeKXMLGUIConfigFile()) {
642 return;
643 }
644
645 KConfigGroup cg(KSharedConfig::openConfig(), configGroup());
646 if (!config) {
647 config = &cg;
648 }
649
650 QList<QAction *> writeActions;
651 if (oneAction) {
652 writeActions.append(oneAction);
653 } else {
654 writeActions = actions();
655 }
656
657 for (QMap<QString, QAction *>::ConstIterator it = d->actionByName.constBegin(); it != d->actionByName.constEnd(); ++it) {
658 QAction *action = it.value();
659 if (!action) {
660 continue;
661 }
662
663 const QString &actionName = it.key();
664
665 // If the action name starts with unnamed- spit out a warning and ignore
666 // it. That name will change at will and will break loading writing
667 if (actionName.startsWith(QLatin1String("unnamed-"))) {
668 qCCritical(DEBUG_KXMLGUI) << "Skipped saving Shortcut for action without name " << action->text() << "!";
669 continue;
670 }
671
672 // Write the shortcut
674 bool bConfigHasAction = !config->readEntry(actionName, QString()).isEmpty();
675 bool bSameAsDefault = (action->shortcuts() == defaultShortcuts(action));
676 // If we're using a global config or this setting
677 // differs from the default, then we want to write.
679
680 // Honor the configIsGlobal() setting
681 if (configIsGlobal()) {
682 flags |= KConfigGroup::Global;
683 }
684
685 if (writeAll || !bSameAsDefault) {
686 // We are instructed to write all shortcuts or the shortcut is
687 // not set to its default value. Write it
689 if (s.isEmpty()) {
690 s = QStringLiteral("none");
691 }
692 qCDebug(DEBUG_KXMLGUI) << "\twriting " << actionName << " = " << s;
693 config->writeEntry(actionName, s, flags);
694
695 } else if (bConfigHasAction) {
696 // Otherwise, this key is the same as default but exists in
697 // config file. Remove it.
698 qCDebug(DEBUG_KXMLGUI) << "\tremoving " << actionName << " because == default";
699 config->deleteEntry(actionName, flags);
700 }
701 }
702 }
703
704 config->sync();
705}
706
707void KActionCollection::slotActionTriggered()
708{
710 if (action) {
712 }
713}
714
715void KActionCollection::slotActionHovered()
716{
718 if (action) {
720 }
721}
722
723// The downcast from a QObject to a QAction triggers UBSan
724// but we're only comparing pointers, so UBSan shouldn't check vptrs
725// Similar to https://github.com/itsBelinda/plog/pull/1/files
726#if defined(__clang__) || __GNUC__ >= 8
727__attribute__((no_sanitize("vptr")))
728#endif
729void KActionCollectionPrivate::_k_actionDestroyed(QObject *obj)
730{
731 // obj isn't really a QAction anymore. So make sure we don't do fancy stuff
732 // with it.
733 QAction *action = static_cast<QAction *>(obj);
734
735 if (!unlistAction(action)) {
736 return;
737 }
738
739 Q_EMIT q->changed();
740}
741
743{
744 if (d->connectHovered && d->connectTriggered) {
745 return;
746 }
747
748 if (signal.methodSignature() == "actionHovered(QAction*)") {
749 if (!d->connectHovered) {
750 d->connectHovered = true;
751 for (QAction *action : std::as_const(d->actions)) {
752 connect(action, &QAction::hovered, this, &KActionCollection::slotActionHovered);
753 }
754 }
755
756 } else if (signal.methodSignature() == "actionTriggered(QAction*)") {
757 if (!d->connectTriggered) {
758 d->connectTriggered = true;
759 for (QAction *action : std::as_const(d->actions)) {
760 connect(action, &QAction::triggered, this, &KActionCollection::slotActionTriggered);
761 }
762 }
763 }
764
766}
767
769{
770 return KActionCollectionPrivate::s_allCollections;
771}
772
774{
775 for (QAction *action : std::as_const(d->actions)) {
776 if (!widget->actions().contains(action)) {
777 widget->addAction(action);
778 }
779 }
780}
781
783{
784 if (!d->associatedWidgets.contains(widget)) {
785 widget->addActions(actions());
786
787 d->associatedWidgets.append(widget);
788 connect(widget, &QObject::destroyed, this, [this](QObject *obj) {
789 d->_k_associatedWidgetDestroyed(obj);
790 });
791 }
792}
793
795{
796 for (QAction *action : std::as_const(d->actions)) {
797 widget->removeAction(action);
798 }
799
800 d->associatedWidgets.removeAll(widget);
801 disconnect(widget, &QObject::destroyed, this, nullptr);
802}
803
804QAction *KActionCollectionPrivate::unlistAction(QAction *action)
805{
806 // ATTENTION:
807 // This method is called with an QObject formerly known as a QAction
808 // during _k_actionDestroyed(). So don't do fancy stuff here that needs a
809 // real QAction!
810
811 // Get the index for the action
812 int index = actions.indexOf(action);
813
814 // Action not found.
815 if (index == -1) {
816 return nullptr;
817 }
818
819 // An action collection can't have the same action twice.
820 Q_ASSERT(actions.indexOf(action, index + 1) == -1);
821
822 // Get the actions name
823 const QString name = action->objectName();
824
825 // Remove the action
826 actionByName.remove(name);
827 actions.removeAt(index);
828
829 // Remove the action from the categories. Should be only one
830 const QList<KActionCategory *> categories = q->findChildren<KActionCategory *>();
831 for (KActionCategory *category : categories) {
832 category->unlistAction(action);
833 }
834
835 return action;
836}
837
839{
840 return d->associatedWidgets;
841}
842
844{
845 for (QWidget *widget : std::as_const(d->associatedWidgets)) {
846 for (QAction *action : std::as_const(d->actions)) {
847 widget->removeAction(action);
848 }
849 }
850
851 d->associatedWidgets.clear();
852}
853
854void KActionCollectionPrivate::_k_associatedWidgetDestroyed(QObject *obj)
855{
856 associatedWidgets.removeAll(static_cast<QWidget *>(obj));
857}
858
859#include "moc_kactioncollection.cpp"
Categorize actions for KShortcutsEditor.
A container for a set of QAction objects.
Q_INVOKABLE QAction * addAction(const QString &name, QAction *action)
Add an action under the given name to the collection.
static QKeySequence defaultShortcut(QAction *action)
Get the default primary shortcut for the given action.
static bool isShortcutsConfigurable(QAction *action)
Returns true if the given action's shortcuts may be configured by the user.
void addActions(const QList< QAction * > &actions)
Adds a list of actions to the collection.
void addAssociatedWidget(QWidget *widget)
Associate all actions in this collection to the given widget, including any actions added after this ...
int count() const
Returns the number of actions in the collection.
~KActionCollection() override
Destructor.
QList< QWidget * > associatedWidgets() const
Return a list of all associated widgets.
void actionHovered(QAction *action)
Indicates that action was hovered.
QString componentDisplayName() const
The display name for the associated component.
void connectNotify(const QMetaMethod &signal) override
Overridden to perform connections when someone wants to know whether an action was highlighted or tri...
void clear()
Clears the entire action collection, deleting all actions.
void importGlobalShortcuts(KConfigGroup *config)
Import from config all configurable global key associations.
void exportGlobalShortcuts(KConfigGroup *config, bool writeDefaults=false) const
Export the current configurable global key associations to config.
void setConfigGroup(const QString &group)
Sets group as the KConfig group with which settings will be loaded and saved.
void setComponentName(const QString &componentName)
Set the componentName associated with this action collection.
void clearAssociatedWidgets()
Clear all associated widgets and remove the actions from those widgets.
static void setShortcutsConfigurable(QAction *action, bool configurable)
Indicate whether the user may configure the action's shortcuts.
void associateWidget(QWidget *widget) const
Associate all actions in this collection to the given widget.
const KXMLGUIClient * parentGUIClient() const
The parent KXMLGUIClient, or null if not available.
const QList< QAction * > actionsWithoutGroup() const
Returns the list of QActions without an QAction::actionGroup() which belong to this action collection...
QAction * takeAction(QAction *action)
Removes an action from the collection.
bool isEmpty() const
Returns whether the action collection is empty or not.
KActionCollection(QObject *parent, const QString &cName=QString())
Constructor.
static void setDefaultShortcut(QAction *action, const QKeySequence &shortcut)
Set the default shortcut for the given action.
const QList< QActionGroup * > actionGroups() const
Returns the list of all QActionGroups associated with actions in this action collection.
static Q_INVOKABLE void setDefaultShortcuts(QAction *action, const QList< QKeySequence > &shortcuts)
Set the default shortcuts for the given action.
void changed()
Emitted when an action has been inserted into, or removed from, this action collection.
void writeSettings(KConfigGroup *config=nullptr, bool writeDefaults=false, QAction *oneAction=nullptr) const
Write the current configurable key associations to config.
void removeAction(QAction *action)
Removes an action from the collection and deletes it.
void inserted(QAction *action)
Indicates that action was inserted into this action collection.
QString componentName() const
The component name with which this class is associated.
static const QList< KActionCollection * > & allCollections()
Access the list of all action collections in existence for this app.
void setComponentDisplayName(const QString &displayName)
Set the component display name associated with this action collection.
static QList< QKeySequence > defaultShortcuts(QAction *action)
Get the default shortcuts for the given action.
void removeAssociatedWidget(QWidget *widget)
Remove an association between all actions in this collection and the given widget,...
void readSettings(KConfigGroup *config=nullptr)
Read all key associations from config.
QList< QAction * > actions() const
Returns the list of QActions which belong to this action collection.
void setConfigGlobal(bool global)
Set whether this action collection's configuration should be global to KDE ( true ),...
QAction * action(int index) const
Return the QAction* at position index in the action collection.
void actionTriggered(QAction *action)
Indicates that action was triggered.
static Q_INVOKABLE bool authorizeAction(const QString &action)
void deleteEntry(const char *key, WriteConfigFlags pFlags=Normal)
void writeEntry(const char *key, const char *value, WriteConfigFlags pFlags=Normal)
QString readEntry(const char *key, const char *aDefault=nullptr) const
bool exists() const
bool sync() override
bool hasShortcut(const QAction *action) const
static KGlobalAccel * self()
bool setShortcut(QAction *action, const QList< QKeySequence > &shortcut, GlobalShortcutLoading loadFlag=Autoloading)
QList< QKeySequence > shortcut(const QAction *action) const
QList< QKeySequence > defaultShortcut(const QAction *action) const
static KSharedConfig::Ptr openConfig(const QString &fileName=QString(), OpenFlags mode=FullConfig, QStandardPaths::StandardLocation type=QStandardPaths::GenericConfigLocation)
A KXMLGUIClient can be used with KXMLGUIFactory to create a GUI from actions and an XML document,...
virtual QString xmlFile() const
This will return the name of the XML file as set by setXMLFile().
static QString readConfigFile(const QString &filename, const QString &componentName=QString())
static bool saveConfigFile(const QDomDocument &doc, const QString &filename, const QString &componentName=QString())
static QDomElement actionPropertiesElement(QDomDocument &doc)
static QDomElement findActionByName(QDomElement &elem, const QString &sName, bool create)
QString name(StandardAction id)
QAction * create(StandardAction id, const QObject *recvr, const char *slot, QObject *parent)
Category category(StandardShortcut id)
const QList< QKeySequence > & shortcut(StandardShortcut id)
QActionGroup * actionGroup() const const
void setEnabled(bool)
void hovered()
void setShortcuts(QKeySequence::StandardKey key)
QList< QKeySequence > shortcuts() const const
void triggered(bool checked)
void setVisible(bool)
ParseResult setContent(QAnyStringView text, ParseOptions options)
QDomNamedNodeMap attributes() const const
void removeAttribute(const QString &name)
void setAttribute(const QString &name, const QString &value)
int count() const const
bool isNull() const const
QDomNode removeChild(const QDomNode &oldChild)
QList< QKeySequence > listFromString(const QString &str, SequenceFormat format)
QString listToString(const QList< QKeySequence > &list, SequenceFormat format)
void append(QList< T > &&value)
bool contains(const AT &value) const const
T & first()
qsizetype indexOf(const AT &value, qsizetype from) const const
bool isEmpty() const const
qsizetype removeAll(const AT &t)
void removeAt(qsizetype i)
T value(qsizetype i) const const
const_iterator constBegin() const const
const_iterator constEnd() const const
size_type remove(const Key &key)
QByteArray methodSignature() const const
Q_EMITQ_EMIT
bool blockSignals(bool block)
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
virtual void connectNotify(const QMetaMethod &signal)
void destroyed(QObject *obj)
bool disconnect(const QMetaObject::Connection &connection)
QList< T > findChildren(Qt::FindChildOptions options) const const
QObject * parent() const const
QVariant property(const char *name) const const
T qobject_cast(QObject *object)
QObject * sender() const const
void setObjectName(QAnyStringView name)
void setParent(QObject *parent)
bool setProperty(const char *name, QVariant &&value)
iterator insert(const T &value)
QList< T > values() const const
QString asprintf(const char *cformat,...)
bool isEmpty() const const
bool startsWith(QChar c, Qt::CaseSensitivity cs) const const
QVariant fromValue(T &&value)
bool isValid() const const
bool toBool() const const
T value() const const
QList< QAction * > actions() const const
QAction * addAction(const QIcon &icon, const QString &text)
void addActions(const QList< QAction * > &actions)
void removeAction(QAction *action)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Jul 19 2024 11:55:33 by doxygen 1.11.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.