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

KDEUI

  • sources
  • kde-4.14
  • kdelibs
  • 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 
47 using namespace KXMLGUI;
48 
49 class KXMLGUIFactoryPrivate : public BuildState
50 {
51 public:
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 
117 QString 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 
142 bool 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 
170 static 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 
190 KXMLGUIFactory::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 
202 KXMLGUIFactory::~KXMLGUIFactory()
203 {
204  foreach (KXMLGUIClient *client, d->m_clients) {
205  client->setFactory ( 0L );
206  }
207  delete d;
208 }
209 
210 void 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 
311 void 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 
327 static 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
334 static 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 
348 void 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 
360 void 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 
397 void 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 
406 void KXMLGUIFactory::forgetClient( KXMLGUIClient *client )
407 {
408  d->m_clients.removeAll( client );
409 }
410 
411 void 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 
469 QList<KXMLGUIClient*> KXMLGUIFactory::clients() const
470 {
471  return d->m_clients;
472 }
473 
474 QWidget *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 
491 QList<QWidget*> KXMLGUIFactory::containers( const QString &tagName )
492 {
493  return d->findRecursive( d->m_rootNode, tagName );
494 }
495 
496 void KXMLGUIFactory::reset()
497 {
498  d->m_rootNode->reset();
499 
500  d->m_rootNode->clearChildren();
501 }
502 
503 void 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 
522 QWidget *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
540 static inline bool equals(const QString& str1, const char* str2)
541 {
542  return str1.compare(QLatin1String(str2), Qt::CaseInsensitive) == 0;
543 }
544 static inline bool equals(const QString& str1, const QString& str2)
545 {
546  return str1.compare(str2, Qt::CaseInsensitive) == 0;
547 }
548 
549 
550 QList<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 
564 void 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 
583 void 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 
596 void 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 
612 void 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 
625 void 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 
673 QDomDocument 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 
699 void 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 
755 int 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
769 QDomElement 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 
783 QDomElement 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  */
QTextStream::setCodec
void setCodec(QTextCodec *codec)
QObject::child
QObject * child(const char *objName, const char *inheritsClass, bool recursiveSearch) const
currentShortcutScheme
static QString currentShortcutScheme()
Definition: kxmlguifactory.cpp:327
QWidget
KShortcutsEditor::AllActions
All actions.
Definition: kshortcutseditor.h:75
KXMLGUIClient::actionCollection
virtual KActionCollection * actionCollection() const
Retrieves the entire action collection for the GUI client.
Definition: kxmlguiclient.cpp:128
kdebug.h
KXMLGUIClient
A KXMLGUIClient can be used with KXMLGUIFactory to create a GUI from actions and an XML document...
Definition: kxmlguiclient.h:46
QDomAttr::name
QString name() const
QDomNode::appendChild
QDomNode appendChild(const QDomNode &newChild)
QByteArray
QDomElement::attribute
QString attribute(const QString &name, const QString &defValue) const
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::KXMLGUIFactory
KXMLGUIFactory(KXMLGUIBuilder *builder, QObject *parent=0)
Constructs a KXMLGUIFactory.
Definition: kxmlguifactory.cpp:190
kactioncollection.h
KStandardShortcut::shortcut
const KShortcut & shortcut(StandardShortcut id)
Returns the keybinding for accel.
Definition: kstandardshortcut.cpp:285
KStandardDirs::locate
static QString locate(const char *type, const QString &filename, const KComponentData &cData=KGlobal::mainComponent())
KXMLGUIFactory::addClient
void addClient(KXMLGUIClient *client)
Creates the GUI described by the QDomDocument of the client, using the client's actions, and merges it with the previously created GUI.
Definition: kxmlguifactory.cpp:210
QAction::setIcon
void setIcon(const QIcon &icon)
kxmlguibuilder.h
KStandardAction::name
const char * name(StandardAction id)
This will return the internal name of a given standard action.
Definition: kstandardaction.cpp:223
QDomNode::nextSiblingElement
QDomElement nextSiblingElement(const QString &tagName) const
kxmlguifactory.h
findActionPropertiesElement
static QDomElement findActionPropertiesElement(const QDomDocument &doc)
Definition: kxmlguifactory.cpp:334
kError
static QDebug kError(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
kshortcut.h
Defines platform-independent classes for keyboard shortcut handling.
QVariant::value
T value() const
KConfig::group
KConfigGroup group(const QByteArray &group)
KConfigGroup::writeEntry
void writeEntry(const QString &key, const QVariant &value, WriteConfigFlags pFlags=Normal)
QObject::removeChild
void removeChild(QObject *object)
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
QDomDocument::documentElement
QDomElement documentElement() const
QDomNode
QDomNode::nodeType
NodeType nodeType() const
equals
static bool equals(const QString &str1, const char *str2)
Definition: kxmlguifactory.cpp:540
QFile::exists
bool exists() const
KAction::DefaultShortcut
The shortcut is a default shortcut - it becomes active when somebody decides to reset shortcuts to de...
Definition: kaction.h:238
KXMLGUIFactory::reset
void reset()
Use this method to free all memory allocated by the KXMLGUIFactory.
Definition: kxmlguifactory.cpp:496
KXMLGUIClient::reloadXML
void reloadXML()
Forces this client to re-read its XML resource file.
Definition: kxmlguiclient.cpp:174
kDebug
static QDebug kDebug(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
QFile
QTextStream
KGlobal::config
KSharedConfigPtr config()
QDomNode::nextSibling
QDomNode nextSibling() const
KShortcut
Represents a keyboard shortcut.
Definition: kshortcut.h:57
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
QDomNode::toElement
QDomElement toElement() const
kshortcutsdialog.h
QDomNamedNodeMap
QObject::name
const char * name() const
kglobal.h
KXMLGUIClient::childClients
QList< KXMLGUIClient * > childClients()
Retrieves a list of all child clients.
Definition: kxmlguiclient.cpp:635
QList::append
void append(const T &value)
QString::fromUtf8
QString fromUtf8(const char *str, int size)
KXMLGUIFactory::plugActionList
void plugActionList(KXMLGUIClient *client, const QString &name, const QList< QAction * > &actionList)
Definition: kxmlguifactory.cpp:564
QAction::isSeparator
bool isSeparator() const
QObject::property
QVariant property(const char *name) const
QDomNode::ownerDocument
QDomDocument ownerDocument() const
KXMLGUIClient::xmlguiBuildDocument
QDomDocument xmlguiBuildDocument() const
Definition: kxmlguiclient.cpp:592
KShortcut::isEmpty
bool isEmpty() const
Returns whether this shortcut contains any nonempty key sequences.
Definition: kshortcut.cpp:144
KXMLGUIBuilder
Implements the creation of the GUI (menubar, menus and toolbars) as requested by the GUI factory...
Definition: kxmlguibuilder.h:41
QDomAttr
KXMLGUIClient::componentData
virtual KComponentData componentData() const
Definition: kxmlguiclient.cpp:144
KXMLGUIClient::endXMLPlug
void endXMLPlug()
Definition: kxmlguiclient.cpp:739
QObject
QDomElement::setAttribute
void setAttribute(const QString &name, const QString &value)
KXMLGUIFactory::unplugActionList
void unplugActionList(KXMLGUIClient *client, const QString &name)
Definition: kxmlguifactory.cpp:583
QString::toInt
int toInt(bool *ok, int base) const
QObject::objectName
objectName
QString::isEmpty
bool isEmpty() const
KXMLGUIFactory::readConfigFile
static QString readConfigFile(const QString &filename, const KComponentData &componentData=KComponentData())
Definition: kxmlguifactory.cpp:117
KActionCollection::actions
QList< QAction * > actions() const
Returns the list of KActions which belong to this action collection.
Definition: kactioncollection.cpp:186
QIODevice::readAll
QByteArray readAll()
KIcon
A wrapper around QIcon that provides KDE icon features.
Definition: kicon.h:40
removeDOMComments
static void removeDOMComments(QDomNode &node)
Removes all QDomComment objects from the specified node and all its children.
Definition: kxmlguifactory.cpp:170
KXMLGUIFactory::makingChanges
void makingChanges(bool)
Emitted when the factory is currently making changes to the GUI, i.e.
KXMLGUIFactory::clientAdded
void clientAdded(KXMLGUIClient *client)
KComponentData::componentName
QString componentName() const
QString
QList< QWidget * >
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
QFile::open
virtual bool open(QFlags< QIODevice::OpenModeFlag > mode)
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
kaction.h
QString::toLower
QString toLower() const
QDomNode::removeChild
QDomNode removeChild(const QDomNode &oldChild)
QDomNode::namedItem
QDomNode namedItem(const QString &name) const
QDomDocument
QDir::isRelativePath
bool isRelativePath(const QString &path)
QDomAttr::value
QString value() const
QDomNode::isNull
bool isNull() const
KShortcutsEditor::LetterShortcutsAllowed
Letter shortcuts are allowed.
Definition: kshortcutseditor.h:86
KConfigGroup
kxmlguiclient.h
QDomNode::firstChild
QDomNode firstChild() const
QString::toLatin1
QByteArray toLatin1() const
KAction::ActiveShortcut
The shortcut will immediately become active but may be reset to "default".
Definition: kaction.h:235
QLatin1String
KXMLGUIFactory::changeShortcutScheme
void changeShortcutScheme(const QString &scheme)
Definition: kxmlguifactory.cpp:397
KStandardDirs::locateLocal
static QString locateLocal(const char *type, const QString &filename, const KComponentData &cData=KGlobal::mainComponent())
QDomNode::cloneNode
QDomNode cloneNode(bool deep) const
QDomNamedNodeMap::length
uint length() const
kstandarddirs.h
QDomNode::firstChildElement
QDomElement firstChildElement(const QString &tagName) const
QAction
KAction
Class to encapsulate user-driven action or event.
Definition: kaction.h:216
QTextCodec::codecForName
QTextCodec * codecForName(const QByteArray &name)
KXMLGUIFactory::refreshActionProperties
void refreshActionProperties()
Use this method to reset and reread action properties (shortcuts, etc.) for all actions.
Definition: kxmlguifactory.cpp:311
KStandardAction::create
KAction * create(StandardAction id, const QObject *recvr, const char *slot, QObject *parent)
Creates an action corresponding to one of the KStandardAction::StandardAction actions, which is connected to the given object and slot, and is owned by parent.
Definition: kstandardaction.cpp:82
QDomNode::toAttr
QDomAttr toAttr() const
KXMLGUIClient::beginXMLPlug
void beginXMLPlug(QWidget *)
Definition: kxmlguiclient.cpp:732
KComponentData::isValid
bool isValid() const
KGlobal::mainComponent
const KComponentData & mainComponent()
kWarning
static QDebug kWarning(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
QVariant::isValid
bool isValid() const
KXMLGUIClient::domDocument
virtual QDomDocument domDocument() const
Definition: kxmlguiclient.cpp:149
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
QObject::setProperty
bool setProperty(const char *name, const QVariant &value)
KStandardGuiItem::cont
KGuiItem cont()
Returns the 'Continue' gui item.
Definition: kstandardguiitem.cpp:234
QDomElement::tagName
QString tagName() const
KXMLGUIClient::prepareXMLUnplug
void prepareXMLUnplug(QWidget *)
Definition: kxmlguiclient.cpp:743
KGlobal::staticQString
const QString & staticQString(const char *str)
QDomDocument::createElement
QDomElement createElement(const QString &tagName)
KXMLGUIFactory::clients
QList< KXMLGUIClient * > clients() const
Returns a list of all clients currently added to this factory.
Definition: kxmlguifactory.cpp:469
kcomponentdata.h
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
QDomNamedNodeMap::item
QDomNode item(int index) const
KShortcutsEditor::LetterShortcutsDisallowed
Shortcuts without a modifier are not allowed, so 'A' would not be valid, whereas 'Ctrl+A' would be...
Definition: kshortcutseditor.h:84
KXMLGUIFactory::clientRemoved
void clientRemoved(KXMLGUIClient *client)
QObject::parent
QObject * parent() const
QDomElement
QString::compare
int compare(const QString &other) const
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
KXMLGUIFactory::saveConfigFile
static bool saveConfigFile(const QDomDocument &doc, const QString &filename, const KComponentData &componentData=KComponentData())
Definition: kxmlguifactory.cpp:142
KConfigGroup::readEntry
T readEntry(const QString &key, const T &aDefault) const
KXMLGUIFactory::~KXMLGUIFactory
~KXMLGUIFactory()
Destructor.
Definition: kxmlguifactory.cpp:202
KXMLGUIFactory::actionPropertiesElement
static QDomElement actionPropertiesElement(QDomDocument &doc)
Definition: kxmlguifactory.cpp:769
QDomNode::toDocument
QDomDocument toDocument() const
KComponentData
KShortcutsDialog
Dialog for configuration of KActionCollection and KGlobalAccel.
Definition: kshortcutsdialog.h:69
KXMLGUIFactory::containers
QList< QWidget * > containers(const QString &tagName)
Definition: kxmlguifactory.cpp:491
KXMLGUIFactory::findActionByName
static QDomElement findActionByName(QDomElement &elem, const QString &sName, bool create)
Definition: kxmlguifactory.cpp:783
QDomDocument::setContent
bool setContent(const QByteArray &data, bool namespaceProcessing, QString *errorMsg, int *errorLine, int *errorColumn)
KXMLGUIClient::setXMLGUIBuildDocument
void setXMLGUIBuildDocument(const QDomDocument &doc)
Definition: kxmlguiclient.cpp:587
QString::toUInt
uint toUInt(bool *ok, int base) const
QVariant
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
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:24:00 by doxygen 1.8.7 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 API Reference

Skip menu "kdelibs 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

Search



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