• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdelibs-4.14.38 API Reference
  • KDE Home
  • Contact Us
 

KDEUI

  • kdeui
  • xmlgui
kxmlguifactory.cpp
Go to the documentation of this file.
1/* This file is part of the KDE libraries
2 Copyright (C) 1999,2000 Simon Hausmann <hausmann@kde.org>
3 Copyright (C) 2000 Kurt Granroth <granroth@kde.org>
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21#include "kxmlguifactory.h"
22#include "kxmlguifactory_p.h"
23#include "kxmlguiclient.h"
24#include "kxmlguibuilder.h"
25
26#include <assert.h>
27
28#include <QtCore/QDir>
29#include <QtXml/QDomDocument>
30#include <QtCore/QFile>
31#include <QtCore/QTextIStream>
32#include <QtGui/QWidget>
33#include <QtCore/QDate>
34#include <QtCore/QVariant>
35#include <QTextCodec>
36
37#include <kdebug.h>
38#include <kcomponentdata.h>
39#include <kglobal.h>
40#include <kshortcut.h>
41#include <kstandarddirs.h>
42
43#include "kaction.h"
44#include "kshortcutsdialog.h"
45#include "kactioncollection.h"
46
47using namespace KXMLGUI;
48
49class KXMLGUIFactoryPrivate : public BuildState
50{
51public:
52 enum ShortcutOption { SetActiveShortcut = 1, SetDefaultShortcut = 2};
53
54 KXMLGUIFactoryPrivate()
55 {
56 static const QString &defaultMergingName = KGlobal::staticQString( "<default>" );
57 static const QString &actionList = KGlobal::staticQString( "actionlist" );
58 static const QString &name = KGlobal::staticQString( "name" );
59
60 m_rootNode = new ContainerNode( 0L, QString(), 0L );
61 m_defaultMergingName = defaultMergingName;
62 tagActionList = actionList;
63 attrName = name;
64 }
65 ~KXMLGUIFactoryPrivate()
66 {
67 delete m_rootNode;
68 }
69
70 void pushState()
71 {
72 m_stateStack.push( *this );
73 }
74
75 void popState()
76 {
77 BuildState::operator=( m_stateStack.pop() );
78 }
79
80 bool emptyState() const { return m_stateStack.isEmpty(); }
81
82 QWidget *findRecursive( KXMLGUI::ContainerNode *node, bool tag );
83 QList<QWidget*> findRecursive( KXMLGUI::ContainerNode *node, const QString &tagName );
84 void applyActionProperties( const QDomElement &element,
85 ShortcutOption shortcutOption = KXMLGUIFactoryPrivate::SetActiveShortcut );
86 void configureAction( QAction *action, const QDomNamedNodeMap &attributes,
87 ShortcutOption shortcutOption = KXMLGUIFactoryPrivate::SetActiveShortcut );
88 void configureAction( QAction *action, const QDomAttr &attribute,
89 ShortcutOption shortcutOption = KXMLGUIFactoryPrivate::SetActiveShortcut );
90
91 QDomDocument shortcutSchemeDoc(KXMLGUIClient *client);
92 void applyShortcutScheme(KXMLGUIClient *client, const QList<QAction*>& actions, const QDomDocument& scheme);
93 void refreshActionProperties(KXMLGUIClient *client, const QList<QAction*>& actions, const QDomDocument& doc);
94 void saveDefaultActionProperties(const QList<QAction*>& actions);
95
96 ContainerNode *m_rootNode;
97
98 QString m_defaultMergingName;
99
100 /*
101 * Contains the container which is searched for in ::container .
102 */
103 QString m_containerName;
104
105 /*
106 * List of all clients
107 */
108 QList<KXMLGUIClient*> m_clients;
109
110 QString tagActionList;
111
112 QString attrName;
113
114 BuildStateStack m_stateStack;
115};
116
117QString KXMLGUIFactory::readConfigFile( const QString &filename, const KComponentData &_componentData )
118{
119 QString xml_file;
120
121 if (!QDir::isRelativePath(filename))
122 xml_file = filename;
123 else
124 {
125 KComponentData componentData = _componentData.isValid() ? _componentData : KGlobal::mainComponent();
126 xml_file = KStandardDirs::locate("data", componentData.componentName() + '/' + filename);
127 if ( !QFile::exists( xml_file ) )
128 xml_file = KStandardDirs::locate( "data", filename );
129 }
130
131 QFile file( xml_file );
132 if ( xml_file.isEmpty() || !file.open( QIODevice::ReadOnly ) )
133 {
134 kError(240) << "No such XML file" << filename;
135 return QString();
136 }
137
138 QByteArray buffer(file.readAll());
139 return QString::fromUtf8(buffer.constData(), buffer.size());
140}
141
142bool KXMLGUIFactory::saveConfigFile( const QDomDocument& doc,
143 const QString& filename, const KComponentData &_componentData )
144{
145 KComponentData componentData = _componentData.isValid() ? _componentData : KGlobal::mainComponent();
146 QString xml_file(filename);
147
148 if (QDir::isRelativePath(xml_file))
149 xml_file = KStandardDirs::locateLocal("data", componentData.componentName() + '/' + filename);
150
151 QFile file( xml_file );
152 if ( xml_file.isEmpty() || !file.open( QIODevice::WriteOnly ) )
153 {
154 kError(240) << "Could not write to" << filename;
155 return false;
156 }
157
158 // write out our document
159 QTextStream ts(&file);
160 ts.setCodec( QTextCodec::codecForName( "UTF-8" ) );
161 ts << doc;
162
163 file.close();
164 return true;
165}
166
170static void removeDOMComments( QDomNode &node )
171{
172 QDomNode n = node.firstChild();
173 while ( !n.isNull() )
174 {
175 if ( n.nodeType() == QDomNode::CommentNode )
176 {
177 QDomNode tmp = n;
178 n = n.nextSibling();
179 node.removeChild( tmp );
180 }
181 else
182 {
183 QDomNode tmp = n;
184 n = n.nextSibling();
185 removeDOMComments( tmp );
186 }
187 }
188}
189
190KXMLGUIFactory::KXMLGUIFactory( KXMLGUIBuilder *builder, QObject *parent )
191 : QObject( parent ),d(new KXMLGUIFactoryPrivate)
192{
193 d->builder = builder;
194 d->guiClient = 0;
195 if ( d->builder )
196 {
197 d->builderContainerTags = d->builder->containerTags();
198 d->builderCustomTags = d->builder->customTags();
199 }
200}
201
202KXMLGUIFactory::~KXMLGUIFactory()
203{
204 foreach (KXMLGUIClient *client, d->m_clients) {
205 client->setFactory ( 0L );
206 }
207 delete d;
208}
209
210void KXMLGUIFactory::addClient( KXMLGUIClient *client )
211{
212 //kDebug(260) << client;
213 if ( client->factory() ) {
214 if ( client->factory() == this )
215 return;
216 else
217 client->factory()->removeClient( client ); //just in case someone does stupid things ;-)
218 }
219
220 if (d->emptyState())
221 emit makingChanges(true);
222 d->pushState();
223
224// QTime dt; dt.start();
225
226 d->guiClient = client;
227
228 // add this client to our client list
229 if ( !d->m_clients.contains( client ) )
230 d->m_clients.append( client );
231 else
232 kDebug(260) << "XMLGUI client already added " << client;
233
234 // Tell the client that plugging in is process and
235 // let it know what builder widget its mainwindow shortcuts
236 // should be attached to.
237 client->beginXMLPlug( d->builder->widget() );
238
239 // try to use the build document for building the client's GUI, as the build document
240 // contains the correct container state information (like toolbar positions, sizes, etc.) .
241 // if there is non available, then use the "real" document.
242 QDomDocument doc = client->xmlguiBuildDocument();
243 if ( doc.documentElement().isNull() )
244 doc = client->domDocument();
245
246 QDomElement docElement = doc.documentElement();
247
248 d->m_rootNode->index = -1;
249
250 // cache some variables
251
252 d->clientName = docElement.attribute( d->attrName );
253 d->clientBuilder = client->clientBuilder();
254
255 if ( d->clientBuilder )
256 {
257 d->clientBuilderContainerTags = d->clientBuilder->containerTags();
258 d->clientBuilderCustomTags = d->clientBuilder->customTags();
259 }
260 else
261 {
262 d->clientBuilderContainerTags.clear();
263 d->clientBuilderCustomTags.clear();
264 }
265
266 // load shortcut schemes, user-defined shortcuts and other action properties
267 d->saveDefaultActionProperties(client->actionCollection()->actions());
268 if (!doc.isNull())
269 d->refreshActionProperties(client, client->actionCollection()->actions(), doc);
270
271 BuildHelper( *d, d->m_rootNode ).build( docElement );
272
273 // let the client know that we built its GUI.
274 client->setFactory( this );
275
276 // call the finalizeGUI method, to fix up the positions of toolbars for example.
277 // ### FIXME : obey client builder
278 // --- Well, toolbars have a bool "positioned", so it doesn't really matter,
279 // if we call positionYourself on all of them each time. (David)
280 d->builder->finalizeGUI( d->guiClient );
281
282 // reset some variables, for safety
283 d->BuildState::reset();
284
285 client->endXMLPlug();
286
287 d->popState();
288
289 emit clientAdded( client );
290
291 // build child clients
292 foreach (KXMLGUIClient *child, client->childClients())
293 addClient( child );
294
295 if (d->emptyState())
296 emit makingChanges(false);
297/*
298 QString unaddedActions;
299 foreach (KActionCollection* ac, KActionCollection::allCollections())
300 foreach (QAction* action, ac->actions())
301 if (action->associatedWidgets().isEmpty())
302 unaddedActions += action->objectName() + ' ';
303
304 if (!unaddedActions.isEmpty())
305 kWarning() << "The following actions are not plugged into the gui (shortcuts will not work): " << unaddedActions;
306*/
307
308// kDebug() << "addClient took " << dt.elapsed();
309}
310
311void KXMLGUIFactory::refreshActionProperties()
312{
313 foreach (KXMLGUIClient *client, d->m_clients)
314 {
315 d->guiClient = client;
316 QDomDocument doc = client->xmlguiBuildDocument();
317 if ( doc.documentElement().isNull() )
318 {
319 client->reloadXML();
320 doc = client->domDocument();
321 }
322 d->refreshActionProperties(client, client->actionCollection()->actions(), doc);
323 }
324 d->guiClient = 0;
325}
326
327static QString currentShortcutScheme()
328{
329 const KConfigGroup cg = KGlobal::config()->group("Shortcut Schemes");
330 return cg.readEntry("Current Scheme", "Default");
331}
332
333// Find the right ActionProperties element, otherwise return null element
334static QDomElement findActionPropertiesElement(const QDomDocument& doc)
335{
336 const QLatin1String tagActionProp("ActionProperties");
337 const QString schemeName = currentShortcutScheme();
338 QDomElement e = doc.documentElement().firstChildElement();
339 for( ; !e.isNull(); e = e.nextSiblingElement() ) {
340 if (QString::compare(e.tagName(), tagActionProp, Qt::CaseInsensitive) == 0
341 && (e.attribute("scheme", "Default") == schemeName) ) {
342 return e;
343 }
344 }
345 return QDomElement();
346}
347
348void KXMLGUIFactoryPrivate::refreshActionProperties(KXMLGUIClient *client, const QList<QAction*>& actions, const QDomDocument& doc)
349{
350 // try to find and apply shortcuts schemes
351 QDomDocument scheme = shortcutSchemeDoc(client);
352 applyShortcutScheme(client, actions, scheme);
353
354 // try to find and apply user-defined shortcuts
355 const QDomElement actionPropElement = findActionPropertiesElement(doc);
356 if ( !actionPropElement.isNull() )
357 applyActionProperties( actionPropElement );
358}
359
360void KXMLGUIFactoryPrivate::saveDefaultActionProperties(const QList<QAction *>& actions)
361{
362 // This method is called every time the user activated a new
363 // kxmlguiclient. We only want to execute the following code only once in
364 // the lifetime of an action.
365 foreach (QAction *action, actions) {
366 // Skip NULL actions or those we have seen already.
367 if (!action || action->property("_k_DefaultShortcut").isValid()) continue;
368
369 if (KAction* kaction = qobject_cast<KAction*>(action)) {
370 // Check if the default shortcut is set
371 KShortcut defaultShortcut = kaction->shortcut(KAction::DefaultShortcut);
372 KShortcut activeShortcut = kaction->shortcut(KAction::ActiveShortcut);
373 //kDebug() << kaction->objectName() << "default=" << defaultShortcut.toString() << "active=" << activeShortcut.toString();
374
375 // Check if we have an empty default shortcut and an non empty
376 // custom shortcut. This should only happen if a developer called
377 // QAction::setShortcut on an KAction. Print out a warning and
378 // correct the mistake
379 if ((!activeShortcut.isEmpty()) && defaultShortcut.isEmpty()) {
380 kError(240) << "Shortcut for KAction " << kaction->objectName() << kaction->text() << "set with QShortcut::setShortcut()! See KAction documentation.";
381 kaction->setProperty("_k_DefaultShortcut", activeShortcut);
382 } else {
383 kaction->setProperty("_k_DefaultShortcut", defaultShortcut);
384 }
385 }
386 else
387 {
388 // A QAction used with KXMLGUI? Set our property and ignore it.
389 if ( !action->isSeparator() )
390 kError(240) << "Attempt to use QAction" << action->objectName() << "with KXMLGUIFactory!";
391 action->setProperty("_k_DefaultShortcut", KShortcut());
392 }
393
394 }
395}
396
397void KXMLGUIFactory::changeShortcutScheme(const QString &scheme)
398{
399 kDebug(260) << "Changing shortcut scheme to" << scheme;
400 KConfigGroup cg = KGlobal::config()->group( "Shortcut Schemes" );
401 cg.writeEntry("Current Scheme", scheme);
402
403 refreshActionProperties();
404}
405
406void KXMLGUIFactory::forgetClient( KXMLGUIClient *client )
407{
408 d->m_clients.removeAll( client );
409}
410
411void KXMLGUIFactory::removeClient( KXMLGUIClient *client )
412{
413 //kDebug(260) << client;
414
415 // don't try to remove the client's GUI if we didn't build it
416 if ( !client || client->factory() != this )
417 return;
418
419 if (d->emptyState())
420 emit makingChanges(true);
421
422 // remove this client from our client list
423 d->m_clients.removeAll( client );
424
425 // remove child clients first (create a copy of the list just in case the
426 // original list is modified directly or indirectly in removeClient())
427 const QList<KXMLGUIClient*> childClients(client->childClients());
428 foreach (KXMLGUIClient *child, childClients)
429 removeClient(child);
430
431 //kDebug(260) << "calling removeRecursive";
432
433 d->pushState();
434
435 // cache some variables
436
437 d->guiClient = client;
438 d->clientName = client->domDocument().documentElement().attribute( d->attrName );
439 d->clientBuilder = client->clientBuilder();
440
441 client->setFactory( 0L );
442
443 // if we don't have a build document for that client, yet, then create one by
444 // cloning the original document, so that saving container information in the
445 // DOM tree does not touch the original document.
446 QDomDocument doc = client->xmlguiBuildDocument();
447 if ( doc.documentElement().isNull() )
448 {
449 doc = client->domDocument().cloneNode( true ).toDocument();
450 client->setXMLGUIBuildDocument( doc );
451 }
452
453 d->m_rootNode->destruct( doc.documentElement(), *d );
454
455 // reset some variables
456 d->BuildState::reset();
457
458 // This will destruct the KAccel object built around the given widget.
459 client->prepareXMLUnplug( d->builder->widget() );
460
461 d->popState();
462
463 if (d->emptyState())
464 emit makingChanges(false);
465
466 emit clientRemoved( client );
467}
468
469QList<KXMLGUIClient*> KXMLGUIFactory::clients() const
470{
471 return d->m_clients;
472}
473
474QWidget *KXMLGUIFactory::container( const QString &containerName, KXMLGUIClient *client,
475 bool useTagName )
476{
477 d->pushState();
478 d->m_containerName = containerName;
479 d->guiClient = client;
480
481 QWidget *result = d->findRecursive( d->m_rootNode, useTagName );
482
483 d->guiClient = 0L;
484 d->m_containerName.clear();
485
486 d->popState();
487
488 return result;
489}
490
491QList<QWidget*> KXMLGUIFactory::containers( const QString &tagName )
492{
493 return d->findRecursive( d->m_rootNode, tagName );
494}
495
496void KXMLGUIFactory::reset()
497{
498 d->m_rootNode->reset();
499
500 d->m_rootNode->clearChildren();
501}
502
503void KXMLGUIFactory::resetContainer( const QString &containerName, bool useTagName )
504{
505 if ( containerName.isEmpty() )
506 return;
507
508 ContainerNode *container = d->m_rootNode->findContainer( containerName, useTagName );
509
510 if ( !container )
511 return;
512
513 ContainerNode *parent = container->parent;
514 if ( !parent )
515 return;
516
517 // resetInternal( container );
518
519 parent->removeChild( container );
520}
521
522QWidget *KXMLGUIFactoryPrivate::findRecursive( KXMLGUI::ContainerNode *node, bool tag )
523{
524 if ( ( ( !tag && node->name == m_containerName ) ||
525 ( tag && node->tagName == m_containerName ) ) &&
526 ( !guiClient || node->client == guiClient ) )
527 return node->container;
528
529 foreach (ContainerNode* child, node->children)
530 {
531 QWidget *cont = findRecursive( child, tag );
532 if ( cont )
533 return cont;
534 }
535
536 return 0L;
537}
538
539// Case insensitive equality without calling toLower which allocates a new string
540static inline bool equals(const QString& str1, const char* str2)
541{
542 return str1.compare(QLatin1String(str2), Qt::CaseInsensitive) == 0;
543}
544static inline bool equals(const QString& str1, const QString& str2)
545{
546 return str1.compare(str2, Qt::CaseInsensitive) == 0;
547}
548
549
550QList<QWidget*> KXMLGUIFactoryPrivate::findRecursive( KXMLGUI::ContainerNode *node,
551 const QString &tagName )
552{
553 QList<QWidget*> res;
554
555 if ( equals(node->tagName, tagName) )
556 res.append( node->container );
557
558 foreach (KXMLGUI::ContainerNode* child, node->children)
559 res << findRecursive( child, tagName );
560
561 return res;
562}
563
564void KXMLGUIFactory::plugActionList( KXMLGUIClient *client, const QString &name,
565 const QList<QAction*> &actionList )
566{
567 d->pushState();
568 d->guiClient = client;
569 d->actionListName = name;
570 d->actionList = actionList;
571 d->clientName = client->domDocument().documentElement().attribute( d->attrName );
572
573 d->m_rootNode->plugActionList( *d );
574
575 // Load shortcuts for these new actions
576 d->saveDefaultActionProperties(actionList);
577 d->refreshActionProperties(client, actionList, client->domDocument());
578
579 d->BuildState::reset();
580 d->popState();
581}
582
583void KXMLGUIFactory::unplugActionList( KXMLGUIClient *client, const QString &name )
584{
585 d->pushState();
586 d->guiClient = client;
587 d->actionListName = name;
588 d->clientName = client->domDocument().documentElement().attribute( d->attrName );
589
590 d->m_rootNode->unplugActionList( *d );
591
592 d->BuildState::reset();
593 d->popState();
594}
595
596void KXMLGUIFactoryPrivate::applyActionProperties( const QDomElement &actionPropElement,
597 ShortcutOption shortcutOption )
598{
599 for (QDomElement e = actionPropElement.firstChildElement();
600 !e.isNull(); e = e.nextSiblingElement()) {
601 if ( !equals(e.tagName(), "action") )
602 continue;
603
604 QAction *action = guiClient->action( e );
605 if ( !action )
606 continue;
607
608 configureAction( action, e.attributes(), shortcutOption );
609 }
610}
611
612void KXMLGUIFactoryPrivate::configureAction( QAction *action, const QDomNamedNodeMap &attributes,
613 ShortcutOption shortcutOption )
614{
615 for ( uint i = 0; i < attributes.length(); i++ )
616 {
617 QDomAttr attr = attributes.item( i ).toAttr();
618 if ( attr.isNull() )
619 continue;
620
621 configureAction( action, attr, shortcutOption );
622 }
623}
624
625void KXMLGUIFactoryPrivate::configureAction( QAction *action, const QDomAttr &attribute,
626 ShortcutOption shortcutOption )
627{
628 static const QString &attrShortcut = KGlobal::staticQString( "shortcut" );
629
630 QString attrName = attribute.name();
631 // If the attribute is a deprecated "accel", change to "shortcut".
632 if ( equals(attrName, "accel") )
633 attrName = attrShortcut;
634
635 // No need to re-set name, particularly since it's "objectName" in Qt4
636 if ( equals(attrName, "name") )
637 return;
638
639 if ( equals(attrName, "icon") ) {
640 action->setIcon( KIcon( attribute.value() ) );
641 return;
642 }
643
644 QVariant propertyValue;
645
646 QVariant::Type propertyType = action->property( attrName.toLatin1() ).type();
647
648 if ( propertyType == QVariant::Int ) {
649 propertyValue = QVariant( attribute.value().toInt() );
650 } else if ( propertyType == QVariant::UInt ) {
651 propertyValue = QVariant( attribute.value().toUInt() );
652 } else if ( propertyType == QVariant::UserType && action->property( attrName.toLatin1() ).userType() == qMetaTypeId<KShortcut>() ) {
653 // Setting the shortcut by property also sets the default shortcut (which is incorrect), so we have to do it directly
654 if (KAction* ka = qobject_cast<KAction*>(action)) {
655 if (attrName=="globalShortcut") {
656 ka->setGlobalShortcut(KShortcut(attribute.value()), KAction::ActiveShortcut);
657 } else {
658 ka->setShortcut(KShortcut(attribute.value()), KAction::ActiveShortcut);
659 }
660 if (shortcutOption & KXMLGUIFactoryPrivate::SetDefaultShortcut)
661 ka->setShortcut(KShortcut(attribute.value()), KAction::DefaultShortcut);
662 return;
663 }
664 propertyValue = KShortcut( attribute.value() );
665 } else {
666 propertyValue = QVariant( attribute.value() );
667 }
668 if (!action->setProperty( attrName.toLatin1(), propertyValue )) {
669 kWarning() << "Error: Unknown action property " << attrName << " will be ignored!";
670 }
671}
672
673QDomDocument KXMLGUIFactoryPrivate::shortcutSchemeDoc(KXMLGUIClient *client)
674{
675 // Get the name of the current shorcut scheme
676 KConfigGroup cg = KGlobal::config()->group( "Shortcut Schemes" );
677 QString schemeName = cg.readEntry("Current Scheme", "Default");
678
679 QDomDocument doc;
680 if (schemeName != "Default")
681 {
682 // Find the document for the shortcut scheme using both current application path
683 // and current xmlguiclient path but making a preference to app path
684 QString schemeFileName = KStandardDirs::locateLocal("data",
685 client->componentData().componentName() + '/' +
686 client->componentData().componentName() + schemeName.toLower() + "shortcuts.rc" );
687
688 QFile schemeFile(schemeFileName);
689 if (schemeFile.open(QIODevice::ReadOnly))
690 {
691// kDebug(260) << "Found shortcut scheme" << schemeFileName;
692 doc.setContent(&schemeFile);
693 schemeFile.close();
694 }
695 }
696 return doc;
697}
698
699void KXMLGUIFactoryPrivate::applyShortcutScheme(KXMLGUIClient *client, const QList<QAction*> &actions, const QDomDocument& scheme)
700{
701 static const QString &actionPropElementName = KGlobal::staticQString( "ActionProperties" );
702
703 KConfigGroup cg = KGlobal::config()->group( "Shortcut Schemes" );
704 QString schemeName = cg.readEntry("Current Scheme", "Default");
705
706 //First clear all existing shortcuts
707 if (schemeName != "Default") {
708 foreach (QAction *action, actions) {
709 if (KAction *kaction = qobject_cast<KAction*>(action)) {
710 kaction->setShortcut(KShortcut(), KAction::ActiveShortcut);
711 // We clear the default shortcut as well because the shortcut scheme will set its own defaults
712 kaction->setShortcut(KShortcut(), KAction::DefaultShortcut);
713 continue;
714 }
715 if (action) {
716 action->setProperty("shortcut", KShortcut());
717 }
718 }
719 } else {
720 // apply saved default shortcuts
721 foreach (QAction *action, actions) {
722 if (KAction *kaction = qobject_cast<KAction*>(action)) {
723 QVariant savedDefaultShortcut = kaction->property("_k_DefaultShortcut");
724 if (savedDefaultShortcut.isValid()) {
725 KShortcut shortcut = savedDefaultShortcut.value<KShortcut>();
726 //kDebug() << "scheme said" << shortcut.toString() << "for action" << kaction->objectName();
727 kaction->setShortcut(shortcut, KAction::ActiveShortcut);
728 kaction->setShortcut(shortcut, KAction::DefaultShortcut);
729 continue;
730 }
731 }
732 if (action) {
733 action->setProperty("shortcut", KShortcut());
734 }
735 }
736 }
737
738 if (scheme.isNull())
739 return;
740
741 QDomElement docElement = scheme.documentElement();
742 QDomElement actionPropElement = docElement.namedItem( actionPropElementName ).toElement();
743
744 //Check if we really have the shortcut configuration here
745 if (!actionPropElement.isNull()) {
746 kDebug(260) << "Applying shortcut scheme for XMLGUI client" << client->componentData().componentName();
747
748 //Apply all shortcuts we have
749 applyActionProperties(actionPropElement, KXMLGUIFactoryPrivate::SetDefaultShortcut);
750 } else {
751 kDebug(260) << "Invalid shortcut scheme file";
752 }
753}
754
755int KXMLGUIFactory::configureShortcuts(bool letterCutsOk , bool bSaveSettings )
756{
757 KShortcutsDialog dlg(KShortcutsEditor::AllActions,
758 letterCutsOk ? KShortcutsEditor::LetterShortcutsAllowed : KShortcutsEditor::LetterShortcutsDisallowed,
759 qobject_cast<QWidget*>(parent()));
760 foreach (KXMLGUIClient *client, d->m_clients) {
761 if(client) {
762 dlg.addCollection(client->actionCollection());
763 }
764 }
765 return dlg.configure(bSaveSettings);
766}
767
768// Find or create
769QDomElement KXMLGUIFactory::actionPropertiesElement( QDomDocument& doc )
770{
771 // first, lets see if we have existing properties
772 QDomElement elem = findActionPropertiesElement(doc);
773
774 // if there was none, create one
775 if(elem.isNull()) {
776 elem = doc.createElement(QLatin1String("ActionProperties"));
777 elem.setAttribute("scheme", currentShortcutScheme());
778 doc.documentElement().appendChild( elem );
779 }
780 return elem;
781}
782
783QDomElement KXMLGUIFactory::findActionByName( QDomElement& elem, const QString& sName, bool create )
784{
785 static const QString& attrName = KGlobal::staticQString( "name" );
786 static const QString& tagAction = KGlobal::staticQString( "Action" );
787 for( QDomNode it = elem.firstChild(); !it.isNull(); it = it.nextSibling() ) {
788 QDomElement e = it.toElement();
789 if( e.attribute( attrName ) == sName )
790 return e;
791 }
792
793 if( create ) {
794 QDomElement act_elem = elem.ownerDocument().createElement( tagAction );
795 act_elem.setAttribute( attrName, sName );
796 elem.appendChild( act_elem );
797 return act_elem;
798 }
799 return QDomElement();
800}
801
802#include "kxmlguifactory.moc"
803
804/* vim: et sw=4
805 */
KActionCollection::actions
QList< QAction * > actions() const
Returns the list of KActions which belong to this action collection.
Definition: kactioncollection.cpp:186
KAction
Class to encapsulate user-driven action or event.
Definition: kaction.h:217
KAction::ActiveShortcut
@ ActiveShortcut
The shortcut will immediately become active but may be reset to "default".
Definition: kaction.h:235
KAction::DefaultShortcut
@ DefaultShortcut
The shortcut is a default shortcut - it becomes active when somebody decides to reset shortcuts to de...
Definition: kaction.h:238
KComponentData
KComponentData::isValid
bool isValid() const
KComponentData::componentName
QString componentName() const
KConfigGroup
KConfigGroup::writeEntry
void writeEntry(const char *key, const char *value, WriteConfigFlags pFlags=Normal)
KConfigGroup::readEntry
QString readEntry(const char *key, const char *aDefault=0) const
KIcon
A wrapper around QIcon that provides KDE icon features.
Definition: kicon.h:41
KShortcut
Represents a keyboard shortcut.
Definition: kshortcut.h:58
KShortcut::isEmpty
bool isEmpty() const
Returns whether this shortcut contains any nonempty key sequences.
Definition: kshortcut.cpp:144
KShortcutsDialog
Dialog for configuration of KActionCollection and KGlobalAccel.
Definition: kshortcutsdialog.h:70
KShortcutsDialog::configure
bool configure(bool saveSettings=true)
Run the dialog and call writeSettings() on the action collections that were added if bSaveSettings is...
Definition: kshortcutsdialog.cpp:166
KShortcutsDialog::addCollection
void addCollection(KActionCollection *, const QString &title=QString())
Add all actions of the collection to the ones displayed and configured by the dialog.
Definition: kshortcutsdialog.cpp:153
KShortcutsEditor::LetterShortcutsDisallowed
@ LetterShortcutsDisallowed
Shortcuts without a modifier are not allowed, so 'A' would not be valid, whereas 'Ctrl+A' would be.
Definition: kshortcutseditor.h:84
KShortcutsEditor::LetterShortcutsAllowed
@ LetterShortcutsAllowed
Letter shortcuts are allowed.
Definition: kshortcutseditor.h:86
KShortcutsEditor::AllActions
@ AllActions
All actions.
Definition: kshortcutseditor.h:75
KStandardDirs::locate
static QString locate(const char *type, const QString &filename, const KComponentData &cData=KGlobal::mainComponent())
KStandardDirs::locateLocal
static QString locateLocal(const char *type, const QString &filename, bool createDir, const KComponentData &cData=KGlobal::mainComponent())
KXMLGUIBuilder
Implements the creation of the GUI (menubar, menus and toolbars) as requested by the GUI factory.
Definition: kxmlguibuilder.h:42
KXMLGUIClient
A KXMLGUIClient can be used with KXMLGUIFactory to create a GUI from actions and an XML document,...
Definition: kxmlguiclient.h:47
KXMLGUIClient::prepareXMLUnplug
void prepareXMLUnplug(QWidget *)
Definition: kxmlguiclient.cpp:743
KXMLGUIClient::reloadXML
void reloadXML()
Forces this client to re-read its XML resource file.
Definition: kxmlguiclient.cpp:174
KXMLGUIClient::domDocument
virtual QDomDocument domDocument() const
Definition: kxmlguiclient.cpp:149
KXMLGUIClient::actionCollection
virtual KActionCollection * actionCollection() const
Retrieves the entire action collection for the GUI client.
Definition: kxmlguiclient.cpp:128
KXMLGUIClient::componentData
virtual KComponentData componentData() const
Definition: kxmlguiclient.cpp:144
KXMLGUIClient::childClients
QList< KXMLGUIClient * > childClients()
Retrieves a list of all child clients.
Definition: kxmlguiclient.cpp:635
KXMLGUIClient::endXMLPlug
void endXMLPlug()
Definition: kxmlguiclient.cpp:739
KXMLGUIClient::factory
KXMLGUIFactory * factory() const
Retrieves a pointer to the KXMLGUIFactory this client is associated with (will return 0 if the client...
Definition: kxmlguiclient.cpp:602
KXMLGUIClient::setXMLGUIBuildDocument
void setXMLGUIBuildDocument(const QDomDocument &doc)
Definition: kxmlguiclient.cpp:587
KXMLGUIClient::beginXMLPlug
void beginXMLPlug(QWidget *)
Definition: kxmlguiclient.cpp:732
KXMLGUIClient::setFactory
void setFactory(KXMLGUIFactory *factory)
This method is called by the KXMLGUIFactory as soon as the client is added to the KXMLGUIFactory's GU...
Definition: kxmlguiclient.cpp:597
KXMLGUIClient::clientBuilder
KXMLGUIBuilder * clientBuilder() const
Retrieves the client's GUI builder or 0 if no client specific builder has been assigned via setClient...
Definition: kxmlguiclient.cpp:647
KXMLGUIClient::xmlguiBuildDocument
QDomDocument xmlguiBuildDocument() const
Definition: kxmlguiclient.cpp:592
KXMLGUIFactory::KXMLGUIFactory
KXMLGUIFactory(KXMLGUIBuilder *builder, QObject *parent=0)
Constructs a KXMLGUIFactory.
Definition: kxmlguifactory.cpp:190
KXMLGUIFactory::readConfigFile
static QString readConfigFile(const QString &filename, const KComponentData &componentData=KComponentData())
Definition: kxmlguifactory.cpp:117
KXMLGUIFactory::plugActionList
void plugActionList(KXMLGUIClient *client, const QString &name, const QList< QAction * > &actionList)
Definition: kxmlguifactory.cpp:564
KXMLGUIFactory::containers
QList< QWidget * > containers(const QString &tagName)
Definition: kxmlguifactory.cpp:491
KXMLGUIFactory::clients
QList< KXMLGUIClient * > clients() const
Returns a list of all clients currently added to this factory.
Definition: kxmlguifactory.cpp:469
KXMLGUIFactory::~KXMLGUIFactory
~KXMLGUIFactory()
Destructor.
Definition: kxmlguifactory.cpp:202
KXMLGUIFactory::removeClient
void removeClient(KXMLGUIClient *client)
Removes the GUI described by the client, by unplugging all provided actions and removing all owned co...
Definition: kxmlguifactory.cpp:411
KXMLGUIFactory::addClient
void addClient(KXMLGUIClient *client)
Creates the GUI described by the QDomDocument of the client, using the client's actions,...
Definition: kxmlguifactory.cpp:210
KXMLGUIFactory::actionPropertiesElement
static QDomElement actionPropertiesElement(QDomDocument &doc)
Definition: kxmlguifactory.cpp:769
KXMLGUIFactory::configureShortcuts
int configureShortcuts(bool bAllowLetterShortcuts=true, bool bSaveSettings=true)
Show a standard configure shortcut for every action in this factory.
Definition: kxmlguifactory.cpp:755
KXMLGUIFactory::reset
void reset()
Use this method to free all memory allocated by the KXMLGUIFactory.
Definition: kxmlguifactory.cpp:496
KXMLGUIFactory::unplugActionList
void unplugActionList(KXMLGUIClient *client, const QString &name)
Definition: kxmlguifactory.cpp:583
KXMLGUIFactory::clientRemoved
void clientRemoved(KXMLGUIClient *client)
KXMLGUIFactory::clientAdded
void clientAdded(KXMLGUIClient *client)
KXMLGUIFactory::findActionByName
static QDomElement findActionByName(QDomElement &elem, const QString &sName, bool create)
Definition: kxmlguifactory.cpp:783
KXMLGUIFactory::makingChanges
void makingChanges(bool)
Emitted when the factory is currently making changes to the GUI, i.e.
KXMLGUIFactory::refreshActionProperties
void refreshActionProperties()
Use this method to reset and reread action properties (shortcuts, etc.) for all actions.
Definition: kxmlguifactory.cpp:311
KXMLGUIFactory::saveConfigFile
static bool saveConfigFile(const QDomDocument &doc, const QString &filename, const KComponentData &componentData=KComponentData())
Definition: kxmlguifactory.cpp:142
KXMLGUIFactory::container
QWidget * container(const QString &containerName, KXMLGUIClient *client, bool useTagName=false)
Use this method to get access to a container widget with the name specified with containerName and wh...
Definition: kxmlguifactory.cpp:474
KXMLGUIFactory::changeShortcutScheme
void changeShortcutScheme(const QString &scheme)
Definition: kxmlguifactory.cpp:397
KXMLGUIFactory::resetContainer
void resetContainer(const QString &containerName, bool useTagName=false)
Use this method to free all memory allocated by the KXMLGUIFactory for a specific container,...
Definition: kxmlguifactory.cpp:503
QAction
QList
QObject
QWidget
kDebug
#define kDebug
kWarning
#define kWarning
kaction.h
kactioncollection.h
kcomponentdata.h
kdebug.h
kglobal.h
kshortcut.h
Defines platform-independent classes for keyboard shortcut handling.
kshortcutsdialog.h
kstandarddirs.h
kxmlguibuilder.h
kxmlguiclient.h
removeDOMComments
static void removeDOMComments(QDomNode &node)
Removes all QDomComment objects from the specified node and all its children.
Definition: kxmlguifactory.cpp:170
findActionPropertiesElement
static QDomElement findActionPropertiesElement(const QDomDocument &doc)
Definition: kxmlguifactory.cpp:334
currentShortcutScheme
static QString currentShortcutScheme()
Definition: kxmlguifactory.cpp:327
equals
static bool equals(const QString &str1, const char *str2)
Definition: kxmlguifactory.cpp:540
kxmlguifactory.h
KGlobal::staticQString
const QString & staticQString(const char *str)
KGlobal::mainComponent
const KComponentData & mainComponent()
KGlobal::config
KSharedConfigPtr config()
KStandardAction::name
const char * name(StandardAction id)
This will return the internal name of a given standard action.
Definition: kstandardaction.cpp:223
KStandardShortcut::shortcut
const KShortcut & shortcut(StandardShortcut id)
Returns the keybinding for accel.
Definition: kstandardshortcut.cpp:285
KXMLGUI
Definition: kxmlguifactory.h:41
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Feb 20 2023 00:00:00 by doxygen 1.9.6 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KDEUI

Skip menu "KDEUI"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Modules
  • Related Pages

kdelibs-4.14.38 API Reference

Skip menu "kdelibs-4.14.38 API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal