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

KDEUI

  • sources
  • kde-4.12
  • kdelibs
  • kdeui
  • xmlgui
kxmlguiclient.cpp
Go to the documentation of this file.
1 /* This file is part of the KDE libraries
2  Copyright (C) 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 version 2 as published by the Free Software Foundation.
8 
9  This library is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  Library General Public License for more details.
13 
14  You should have received a copy of the GNU Library General Public License
15  along with this library; see the file COPYING.LIB. If not, write to
16  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  Boston, MA 02110-1301, USA.
18 */
19 
20 #include "kxmlguiclient.h"
21 #include "kxmlguiversionhandler_p.h"
22 #include "kxmlguifactory.h"
23 #include "kxmlguibuilder.h"
24 
25 #include <QtCore/QDir>
26 #include <QtCore/QFile>
27 #include <QtXml/QDomDocument>
28 #include <QtCore/QTextIStream>
29 #include <QtCore/QRegExp>
30 #include <QtCore/QPointer>
31 
32 #include <kcomponentdata.h>
33 #include <kstandarddirs.h>
34 #include <kdebug.h>
35 #include <kauthorized.h>
36 
37 #include "kaction.h"
38 #include "kactioncollection.h"
39 
40 #include <assert.h>
41 
42 class KXMLGUIClientPrivate
43 {
44 public:
45  KXMLGUIClientPrivate()
46  : m_componentData(KGlobal::mainComponent()),
47  m_actionCollection(0),
48  m_parent(0L),
49  m_builder(0L)
50  {
51  }
52  ~KXMLGUIClientPrivate()
53  {
54  }
55 
56  bool mergeXML( QDomElement &base, QDomElement &additive,
57  KActionCollection *actionCollection );
58  bool isEmptyContainer(const QDomElement& base,
59  KActionCollection *actionCollection) const;
60 
61  QDomElement findMatchingElement( const QDomElement &base,
62  const QDomElement &additive );
63 
64  KComponentData m_componentData;
65 
66  QDomDocument m_doc;
67  KActionCollection *m_actionCollection;
68  QDomDocument m_buildDocument;
69  QPointer<KXMLGUIFactory> m_factory;
70  KXMLGUIClient *m_parent;
71  //QPtrList<KXMLGUIClient> m_supers;
72  QList<KXMLGUIClient*> m_children;
73  KXMLGUIBuilder *m_builder;
74  QString m_xmlFile;
75  QString m_localXMLFile;
76 
77  // Actions to enable/disable on a state change
78  QMap<QString,KXMLGUIClient::StateChange> m_actionsStateMap;
79 };
80 
81 
82 KXMLGUIClient::KXMLGUIClient()
83  : d( new KXMLGUIClientPrivate )
84 {
85 }
86 
87 KXMLGUIClient::KXMLGUIClient( KXMLGUIClient *parent )
88  : d( new KXMLGUIClientPrivate )
89 {
90  parent->insertChildClient( this );
91 }
92 
93 KXMLGUIClient::~KXMLGUIClient()
94 {
95  if ( d->m_parent ) {
96  d->m_parent->removeChildClient( this );
97  }
98 
99  if ( d->m_factory ) {
100  kWarning(240) << this << "deleted without having been removed from the factory first. This will leak standalone popupmenus and could lead to crashes.";
101  d->m_factory->forgetClient(this);
102  }
103 
104  foreach (KXMLGUIClient* client, d->m_children) {
105  if (d->m_factory)
106  d->m_factory->forgetClient(client);
107  assert( client->d->m_parent == this );
108  client->d->m_parent = 0;
109  }
110 
111  delete d->m_actionCollection;
112  delete d;
113 }
114 
115 QAction *KXMLGUIClient::action( const char *name ) const
116 {
117  QAction* act = actionCollection()->action( name );
118  if ( !act ) {
119  foreach (KXMLGUIClient* client, d->m_children) {
120  act = client->actionCollection()->action( name );
121  if ( act )
122  break;
123  }
124  }
125  return act;
126 }
127 
128 KActionCollection *KXMLGUIClient::actionCollection() const
129 {
130  if ( !d->m_actionCollection )
131  {
132  d->m_actionCollection = new KActionCollection( this );
133  d->m_actionCollection->setObjectName( "KXMLGUIClient-KActionCollection" );
134  }
135  return d->m_actionCollection;
136 }
137 
138 QAction *KXMLGUIClient::action( const QDomElement &element ) const
139 {
140  static const QString &attrName = KGlobal::staticQString( "name" );
141  return actionCollection()->action( qPrintable(element.attribute( attrName )) );
142 }
143 
144 KComponentData KXMLGUIClient::componentData() const
145 {
146  return d->m_componentData;
147 }
148 
149 QDomDocument KXMLGUIClient::domDocument() const
150 {
151  return d->m_doc;
152 }
153 
154 QString KXMLGUIClient::xmlFile() const
155 {
156  return d->m_xmlFile;
157 }
158 
159 QString KXMLGUIClient::localXMLFile() const
160 {
161  if ( !d->m_localXMLFile.isEmpty() )
162  return d->m_localXMLFile;
163 
164  if ( !QDir::isRelativePath(d->m_xmlFile) )
165  return QString(); // can't save anything here
166 
167  if (d->m_xmlFile.isEmpty()) // setXMLFile not called at all, can't save. Use case: ToolBarHandler
168  return QString();
169 
170  return KStandardDirs::locateLocal( "data", componentData().componentName() + '/' + d->m_xmlFile );
171 }
172 
173 
174 void KXMLGUIClient::reloadXML()
175 {
176  // TODO: this method can't be used for the KXmlGuiWindow, since it doesn't merge in ui_standards.rc!
177  // -> KDE5: load ui_standards_rc in setXMLFile using a flag, and remember that flag?
178  // and then KEditToolBar can use reloadXML.
179  QString file( xmlFile() );
180  if ( !file.isEmpty() )
181  setXMLFile( file );
182 }
183 
184 void KXMLGUIClient::setComponentData(const KComponentData &componentData)
185 {
186  d->m_componentData = componentData;
187  actionCollection()->setComponentData( componentData );
188  if ( d->m_builder )
189  d->m_builder->setBuilderClient( this );
190 }
191 
192 void KXMLGUIClient::loadStandardsXmlFile()
193 {
194  const QString file = KStandardDirs::locate("config", "ui/ui_standards.rc", componentData());
195  if (file.isEmpty()) {
196  kWarning() << "ui/ui_standards.rc not found in" << componentData().dirs()->resourceDirs("config");
197  } else {
198  const QString doc = KXMLGUIFactory::readConfigFile( file );
199  setXML( doc );
200  }
201 }
202 
203 void KXMLGUIClient::setXMLFile( const QString& _file, bool merge, bool setXMLDoc )
204 {
205  // store our xml file name
206  if ( !_file.isNull() )
207  d->m_xmlFile = _file;
208 
209  if ( !setXMLDoc )
210  return;
211 
212  QString file = _file;
213  QStringList allFiles;
214  if ( !QDir::isRelativePath( file ) ) {
215  allFiles.append( file );
216  } else {
217  const QString filter = componentData().componentName() + '/' + _file;
218  allFiles = componentData().dirs()->findAllResources("data", filter) +
219  componentData().dirs()->findAllResources("data", _file);
220  }
221  if ( allFiles.isEmpty() && !_file.isEmpty() ) {
222  // if a non-empty file gets passed and we can't find it,
223  // inform the developer using some debug output
224  kWarning() << "cannot find .rc file" << _file << "for component" << componentData().componentName();
225  }
226 
227  // make sure to merge the settings from any file specified by setLocalXMLFile()
228  if ( !d->m_localXMLFile.isEmpty() && !file.endsWith("ui_standards.rc") ) {
229  const bool exists = QDir::isRelativePath(d->m_localXMLFile) || QFile::exists(d->m_localXMLFile);
230  if (exists && !allFiles.contains(d->m_localXMLFile))
231  allFiles.prepend( d->m_localXMLFile );
232  }
233 
234  QString doc;
235  if ( !allFiles.isEmpty() )
236  file = findMostRecentXMLFile(allFiles, doc);
237 
238  // Always call setXML, even on error, so that we don't keep all ui_standards.rc menus.
239  setXML( doc, merge );
240 }
241 
242 void KXMLGUIClient::setLocalXMLFile( const QString &file )
243 {
244  d->m_localXMLFile = file;
245 }
246 
247 void KXMLGUIClient::replaceXMLFile( const QString& xmlfile, const QString& localxmlfile, bool merge )
248 {
249  if ( !QDir::isAbsolutePath ( xmlfile ) ) {
250  kWarning() << "xml file" << xmlfile << "is not an absolute path";
251  }
252 
253  setLocalXMLFile ( localxmlfile );
254  setXMLFile ( xmlfile, merge );
255 }
256 
257 void KXMLGUIClient::setXML( const QString &document, bool merge )
258 {
259  QDomDocument doc;
260  QString errorMsg;
261  int errorLine, errorColumn;
262  // QDomDocument raises a parse error on empty document, but we accept no app-specific document,
263  // in which case you only get ui_standards.rc layout.
264  bool result = document.isEmpty() || doc.setContent(document, &errorMsg, &errorLine, &errorColumn);
265  if ( result ) {
266  setDOMDocument( doc, merge );
267  } else {
268 #ifdef NDEBUG
269  kError(240) << "Error parsing XML document:" << errorMsg << "at line" << errorLine << "column" << errorColumn;
270  setDOMDocument(QDomDocument(), merge); // otherwise empty menus from ui_standards.rc stay around
271 #else
272  kFatal() << "Error parsing XML document:" << errorMsg << "at line" << errorLine << "column" << errorColumn;
273 #endif
274  }
275 }
276 
277 void KXMLGUIClient::setDOMDocument( const QDomDocument &document, bool merge )
278 {
279  if ( merge && !d->m_doc.isNull() )
280  {
281  QDomElement base = d->m_doc.documentElement();
282 
283  QDomElement e = document.documentElement();
284 
285  // merge our original (global) xml with our new one
286  d->mergeXML(base, e, actionCollection());
287 
288  // reassign our pointer as mergeXML might have done something
289  // strange to it
290  base = d->m_doc.documentElement();
291 
292  //kDebug(260) << "Result of xmlgui merging:" << d->m_doc.toString();
293 
294  // we want some sort of failsafe.. just in case
295  if ( base.isNull() )
296  d->m_doc = document;
297  }
298  else
299  {
300  d->m_doc = document;
301  }
302 
303  setXMLGUIBuildDocument( QDomDocument() );
304 }
305 
306 // if (equals(a,b)) is more readable than if (a.compare(b, Qt::CaseInsensitive)==0)
307 static bool equalstr(const QString& a, const QString& b) {
308  return a.compare(b, Qt::CaseInsensitive) == 0;
309 }
310 
311 bool KXMLGUIClientPrivate::mergeXML( QDomElement &base, QDomElement &additive, KActionCollection *actionCollection )
312 {
313  static const QString &tagAction = KGlobal::staticQString( "Action" );
314  static const QString &tagMerge = KGlobal::staticQString( "Merge" );
315  static const QString &tagSeparator = KGlobal::staticQString( "Separator" );
316  static const QString &attrName = KGlobal::staticQString( "name" );
317  static const QString &attrAppend = KGlobal::staticQString( "append" );
318  static const QString &attrWeakSeparator = KGlobal::staticQString( "weakSeparator" );
319  static const QString &tagMergeLocal = KGlobal::staticQString( "MergeLocal" );
320  static const QString &tagText = KGlobal::staticQString( "text" );
321  static const QString &attrAlreadyVisited = KGlobal::staticQString( "alreadyVisited" );
322  static const QString &attrNoMerge = KGlobal::staticQString( "noMerge" );
323  static const QString &attrOne = KGlobal::staticQString( "1" );
324 
325  // there is a possibility that we don't want to merge in the
326  // additive.. rather, we might want to *replace* the base with the
327  // additive. this can be for any container.. either at a file wide
328  // level or a simple container level. we look for the 'noMerge'
329  // tag, in any event and just replace the old with the new
330  if ( additive.attribute(attrNoMerge) == attrOne ) // ### use toInt() instead? (Simon)
331  {
332  base.parentNode().replaceChild(additive, base);
333  return true;
334  } else {
335  // Merge attributes
336  {
337  const QDomNamedNodeMap attribs = additive.attributes();
338  const uint attribcount = attribs.count();
339 
340  for(uint i = 0; i < attribcount; ++i) {
341  const QDomNode node = attribs.item(i);
342  base.setAttribute(node.nodeName(), node.nodeValue());
343  }
344  }
345 
346  // iterate over all elements in the container (of the global DOM tree)
347  QDomNode n = base.firstChild();
348  while ( !n.isNull() )
349  {
350  QDomElement e = n.toElement();
351  n = n.nextSibling(); // Advance now so that we can safely delete e
352  if (e.isNull())
353  continue;
354 
355  const QString tag = e.tagName();
356 
357  // if there's an action tag in the global tree and the action is
358  // not implemented, then we remove the element
359  if (equalstr(tag, tagAction)) {
360  const QString name = e.attribute(attrName);
361  if (!actionCollection->action(name) ||
362  !KAuthorized::authorizeKAction(name))
363  {
364  // remove this child as we aren't using it
365  base.removeChild( e );
366  continue;
367  }
368  }
369 
370  // if there's a separator defined in the global tree, then add an
371  // attribute, specifying that this is a "weak" separator
372  else if (equalstr(tag, tagSeparator)) {
373  e.setAttribute( attrWeakSeparator, (uint)1 );
374 
375  // okay, hack time. if the last item was a weak separator OR
376  // this is the first item in a container, then we nuke the
377  // current one
378  QDomElement prev = e.previousSibling().toElement();
379  if (prev.isNull() ||
380  (equalstr(prev.tagName(), tagSeparator) && !prev.attribute(attrWeakSeparator).isNull() ) ||
381  (equalstr(prev.tagName(), tagText))) {
382  // the previous element was a weak separator or didn't exist
383  base.removeChild( e );
384  continue;
385  }
386  }
387 
388  // the MergeLocal tag lets us specify where non-standard elements
389  // of the local tree shall be merged in. After inserting the
390  // elements we delete this element
391  else if (equalstr(tag, tagMergeLocal)) {
392  QDomNode it = additive.firstChild();
393  while ( !it.isNull() )
394  {
395  QDomElement newChild = it.toElement();
396  it = it.nextSibling();
397  if (newChild.isNull() )
398  continue;
399 
400  if (equalstr(newChild.tagName(), tagText))
401  continue;
402 
403  if ( newChild.attribute( attrAlreadyVisited ) == attrOne )
404  continue;
405 
406  QString itAppend( newChild.attribute( attrAppend ) );
407  QString elemName( e.attribute( attrName ) );
408 
409  if ( ( itAppend.isNull() && elemName.isEmpty() ) ||
410  ( itAppend == elemName ) )
411  {
412  // first, see if this new element matches a standard one in
413  // the global file. if it does, then we skip it as it will
414  // be merged in, later
415  QDomElement matchingElement = findMatchingElement( newChild, base );
416  if (matchingElement.isNull() || equalstr(newChild.tagName(), tagSeparator))
417  base.insertBefore( newChild, e );
418  }
419  }
420 
421  base.removeChild( e );
422  continue;
423  }
424 
425  else if (equalstr(tag, tagText)) {
426  continue;
427  }
428  else if (equalstr(tag, tagMerge)) {
429  continue;
430  }
431 
432  // in this last case we check for a separator tag and, if not, we
433  // can be sure that it is a container --> proceed with child nodes
434  // recursively and delete the just proceeded container item in
435  // case it is empty (if the recursive call returns true)
436  else {
437  QDomElement matchingElement = findMatchingElement( e, additive );
438  if ( !matchingElement.isNull() )
439  {
440  matchingElement.setAttribute( attrAlreadyVisited, (uint)1 );
441 
442  if ( mergeXML( e, matchingElement, actionCollection ) )
443  {
444  base.removeChild( e );
445  additive.removeChild(matchingElement); // make sure we don't append it below
446  continue;
447  }
448 
449  continue;
450  }
451  else
452  {
453  // this is an important case here! We reach this point if the
454  // "local" tree does not contain a container definition for
455  // this container. However we have to call mergeXML recursively
456  // and make it check if there are actions implemented for this
457  // container. *If* none, then we can remove this container now
458  QDomElement dummy;
459  if ( mergeXML( e, dummy, actionCollection ) )
460  base.removeChild( e );
461  continue;
462  }
463  }
464  }
465 
466  //here we append all child elements which were not inserted
467  //previously via the LocalMerge tag
468  n = additive.firstChild();
469  while ( !n.isNull() )
470  {
471  QDomElement e = n.toElement();
472  n = n.nextSibling(); // Advance now so that we can safely delete e
473  if (e.isNull())
474  continue;
475 
476  QDomElement matchingElement = findMatchingElement( e, base );
477 
478  if ( matchingElement.isNull() )
479  {
480  base.appendChild( e );
481  }
482  }
483 
484  // do one quick check to make sure that the last element was not
485  // a weak separator
486  QDomElement last = base.lastChild().toElement();
487  if (equalstr(last.tagName(), tagSeparator) &&
488  (!last.attribute(attrWeakSeparator).isNull())) {
489  base.removeChild( last );
490  }
491  }
492 
493  return isEmptyContainer(base, actionCollection);
494 }
495 
496 bool KXMLGUIClientPrivate::isEmptyContainer(const QDomElement& base, KActionCollection *actionCollection) const
497 {
498  // now we check if we are empty (in which case we return "true", to
499  // indicate the caller that it can delete "us" (the base element
500  // argument of "this" call)
501  QDomNode n = base.firstChild();
502  while (!n.isNull()) {
503  const QDomElement e = n.toElement();
504  n = n.nextSibling(); // Advance now so that we can safely delete e
505  if (e.isNull())
506  continue;
507 
508  const QString tag = e.tagName();
509 
510  static const QString &tagAction = KGlobal::staticQString("Action");
511  static const QString &tagSeparator = KGlobal::staticQString("Separator");
512  static const QString &tagText = KGlobal::staticQString("text");
513  static const QString &tagMerge = KGlobal::staticQString("Merge");
514  if (equalstr(tag, tagAction)) {
515  // if base contains an implemented action, then we must not get
516  // deleted (note that the actionCollection contains both,
517  // "global" and "local" actions)
518  static const QString &attrName = KGlobal::staticQString("name");
519  if (actionCollection->action(e.attribute(attrName))) {
520  return false;
521  }
522  }
523  else if (equalstr(tag, tagSeparator)) {
524  // if we have a separator which has *not* the weak attribute
525  // set, then it must be owned by the "local" tree in which case
526  // we must not get deleted either
527  static const QString &attrWeakSeparator = KGlobal::staticQString("weakSeparator");
528  const QString weakAttr = e.attribute(attrWeakSeparator);
529  if (weakAttr.isEmpty() || weakAttr.toInt() != 1) {
530  return false;
531  }
532  }
533 
534  else if (equalstr(tag, tagMerge)) {
535  continue;
536  }
537 
538  // a text tag is NOT enough to spare this container
539  else if (equalstr(tag, tagText)) {
540  continue;
541  }
542 
543  // what's left are non-empty containers! *don't* delete us in this
544  // case (at this position we can be *sure* that the container is
545  // *not* empty, as the recursive call for it was in the first loop
546  // which deleted the element in case the call returned "true"
547  else {
548  return false;
549  }
550  }
551 
552  return true; // I'm empty, please delete me.
553 }
554 
555 QDomElement KXMLGUIClientPrivate::findMatchingElement( const QDomElement &base, const QDomElement &additive )
556 {
557  static const QString &tagAction = KGlobal::staticQString( "Action" );
558  static const QString &tagMergeLocal = KGlobal::staticQString( "MergeLocal" );
559  static const QString &attrName = KGlobal::staticQString( "name" );
560 
561  QDomNode n = additive.firstChild();
562  while ( !n.isNull() )
563  {
564  QDomElement e = n.toElement();
565  n = n.nextSibling(); // Advance now so that we can safely delete e -- TODO we don't, so simplify this
566  if (e.isNull())
567  continue;
568 
569  const QString tag = e.tagName();
570  // skip all action and merge tags as we will never use them
571  if (equalstr(tag, tagAction)
572  || equalstr(tag, tagMergeLocal)) {
573  continue;
574  }
575 
576  // now see if our tags are equivalent
577  if (equalstr(tag, base.tagName()) &&
578  e.attribute(attrName) == base.attribute(attrName)) {
579  return e;
580  }
581  }
582 
583  // nope, return a (now) null element
584  return QDomElement();
585 }
586 
587 void KXMLGUIClient::setXMLGUIBuildDocument( const QDomDocument &doc )
588 {
589  d->m_buildDocument = doc;
590 }
591 
592 QDomDocument KXMLGUIClient::xmlguiBuildDocument() const
593 {
594  return d->m_buildDocument;
595 }
596 
597 void KXMLGUIClient::setFactory( KXMLGUIFactory *factory )
598 {
599  d->m_factory = factory;
600 }
601 
602 KXMLGUIFactory *KXMLGUIClient::factory() const
603 {
604  return d->m_factory;
605 }
606 
607 KXMLGUIClient *KXMLGUIClient::parentClient() const
608 {
609  return d->m_parent;
610 }
611 
612 void KXMLGUIClient::insertChildClient( KXMLGUIClient *child )
613 {
614  if ( child->d->m_parent )
615  child->d->m_parent->removeChildClient( child );
616  d->m_children.append( child );
617  child->d->m_parent = this;
618 }
619 
620 void KXMLGUIClient::removeChildClient( KXMLGUIClient *child )
621 {
622  assert( d->m_children.contains( child ) );
623  d->m_children.removeAll( child );
624  child->d->m_parent = 0;
625 }
626 
627 /*bool KXMLGUIClient::addSuperClient( KXMLGUIClient *super )
628 {
629  if ( d->m_supers.contains( super ) )
630  return false;
631  d->m_supers.append( super );
632  return true;
633 }*/
634 
635 QList<KXMLGUIClient*> KXMLGUIClient::childClients()
636 {
637  return d->m_children;
638 }
639 
640 void KXMLGUIClient::setClientBuilder( KXMLGUIBuilder *builder )
641 {
642  d->m_builder = builder;
643  if ( builder )
644  builder->setBuilderComponentData( componentData() );
645 }
646 
647 KXMLGUIBuilder *KXMLGUIClient::clientBuilder() const
648 {
649  return d->m_builder;
650 }
651 
652 void KXMLGUIClient::plugActionList( const QString &name, const QList<QAction*> &actionList )
653 {
654  if ( !d->m_factory )
655  return;
656 
657  d->m_factory->plugActionList( this, name, actionList );
658 }
659 
660 void KXMLGUIClient::unplugActionList( const QString &name )
661 {
662  if ( !d->m_factory )
663  return;
664 
665  d->m_factory->unplugActionList( this, name );
666 }
667 
668 QString KXMLGUIClient::findMostRecentXMLFile( const QStringList &files, QString &doc )
669 {
670  KXmlGuiVersionHandler versionHandler(files);
671  doc = versionHandler.finalDocument();
672  return versionHandler.finalFile();
673 }
674 
675 void KXMLGUIClient::addStateActionEnabled(const QString& state,
676  const QString& action)
677 {
678  StateChange stateChange = getActionsToChangeForState(state);
679 
680  stateChange.actionsToEnable.append( action );
681  //kDebug(260) << "KXMLGUIClient::addStateActionEnabled( " << state << ", " << action << ")";
682 
683  d->m_actionsStateMap.insert( state, stateChange );
684 }
685 
686 
687 void KXMLGUIClient::addStateActionDisabled(const QString& state,
688  const QString& action)
689 {
690  StateChange stateChange = getActionsToChangeForState(state);
691 
692  stateChange.actionsToDisable.append( action );
693  //kDebug(260) << "KXMLGUIClient::addStateActionDisabled( " << state << ", " << action << ")";
694 
695  d->m_actionsStateMap.insert( state, stateChange );
696 }
697 
698 
699 KXMLGUIClient::StateChange KXMLGUIClient::getActionsToChangeForState(const QString& state)
700 {
701  return d->m_actionsStateMap[state];
702 }
703 
704 
705 void KXMLGUIClient::stateChanged(const QString &newstate, KXMLGUIClient::ReverseStateChange reverse)
706 {
707  StateChange stateChange = getActionsToChangeForState(newstate);
708 
709  bool setTrue = (reverse == StateNoReverse);
710  bool setFalse = !setTrue;
711 
712  // Enable actions which need to be enabled...
713  //
714  for ( QStringList::const_iterator it = stateChange.actionsToEnable.constBegin();
715  it != stateChange.actionsToEnable.constEnd(); ++it ) {
716 
717  QAction *action = actionCollection()->action(qPrintable((*it)));
718  if (action) action->setEnabled(setTrue);
719  }
720 
721  // and disable actions which need to be disabled...
722  //
723  for ( QStringList::const_iterator it = stateChange.actionsToDisable.constBegin();
724  it != stateChange.actionsToDisable.constEnd(); ++it ) {
725 
726  QAction *action = actionCollection()->action(qPrintable((*it)));
727  if (action) action->setEnabled(setFalse);
728  }
729 
730 }
731 
732 void KXMLGUIClient::beginXMLPlug( QWidget* w )
733 {
734  actionCollection()->addAssociatedWidget( w );
735  foreach (KXMLGUIClient* client, d->m_children)
736  client->beginXMLPlug( w );
737 }
738 
739 void KXMLGUIClient::endXMLPlug()
740 {
741 }
742 
743 void KXMLGUIClient::prepareXMLUnplug( QWidget * w )
744 {
745  actionCollection()->removeAssociatedWidget( w );
746  foreach (KXMLGUIClient* client, d->m_children)
747  client->prepareXMLUnplug( w );
748 }
749 
750 void KXMLGUIClient::virtual_hook( int, void* )
751 { /*BASE::virtual_hook( id, data );*/ }
KActionCollection::removeAssociatedWidget
void removeAssociatedWidget(QWidget *widget)
Remove an association between all actions in this collection and the given widget, i.e.
Definition: kactioncollection.cpp:718
KActionCollection
A container for a set of QAction objects.
Definition: kactioncollection.h:56
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
kauthorized.h
KXMLGUIClient::replaceXMLFile
void replaceXMLFile(const QString &xmlfile, const QString &localxmlfile, bool merge=false)
Sets a new xmlFile() and localXMLFile().
Definition: kxmlguiclient.cpp:247
KXMLGUIClient::removeChildClient
void removeChildClient(KXMLGUIClient *child)
Removes the given child from the client's children list.
Definition: kxmlguiclient.cpp:620
kactioncollection.h
KStandardDirs::locate
static QString locate(const char *type, const QString &filename, const KComponentData &cData=KGlobal::mainComponent())
KXMLGUIClient::StateChange::actionsToEnable
QStringList actionsToEnable
Definition: kxmlguiclient.h:265
QWidget
kxmlguibuilder.h
KXMLGUIClient::setClientBuilder
void setClientBuilder(KXMLGUIBuilder *builder)
A client can have an own KXMLGUIBuilder.
Definition: kxmlguiclient.cpp:640
KXMLGUIClient::loadStandardsXmlFile
void loadStandardsXmlFile()
Load the ui_standards.rc file.
Definition: kxmlguiclient.cpp:192
KStandardAction::name
const char * name(StandardAction id)
This will return the internal name of a given standard action.
Definition: kstandardaction.cpp:223
kxmlguifactory.h
kError
static QDebug kError(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
KXMLGUIClient::setXMLFile
virtual void setXMLFile(const QString &file, bool merge=false, bool setXMLDoc=true)
Sets the name of the rc file containing the XML for the part.
Definition: kxmlguiclient.cpp:203
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::xmlFile
virtual QString xmlFile() const
This will return the name of the XML file as set by setXMLFile().
Definition: kxmlguiclient.cpp:154
QString
KXMLGUIClient::localXMLFile
virtual QString localXMLFile() const
Definition: kxmlguiclient.cpp:159
KXMLGUIClient::setDOMDocument
virtual void setDOMDocument(const QDomDocument &document, bool merge=false)
Sets the Document for the part, describing the layout of the GUI.
Definition: kxmlguiclient.cpp:277
KXMLGUIClient::reloadXML
void reloadXML()
Forces this client to re-read its XML resource file.
Definition: kxmlguiclient.cpp:174
KXMLGUIClient::getActionsToChangeForState
StateChange getActionsToChangeForState(const QString &state)
Definition: kxmlguiclient.cpp:699
KXMLGUIClient::StateNoReverse
Definition: kxmlguiclient.h:262
KXMLGUIClient::setLocalXMLFile
virtual void setLocalXMLFile(const QString &file)
Set the full path to the "local" xml file, the one used for saving toolbar and shortcut changes...
Definition: kxmlguiclient.cpp:242
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::StateChange::actionsToDisable
QStringList actionsToDisable
Definition: kxmlguiclient.h:266
KXMLGUIClient::childClients
QList< KXMLGUIClient * > childClients()
Retrieves a list of all child clients.
Definition: kxmlguiclient.cpp:635
KXMLGUIClient::stateChanged
virtual void stateChanged(const QString &newstate, ReverseStateChange reverse=StateNoReverse)
Actions can collectively be assigned a "State".
Definition: kxmlguiclient.cpp:705
KXMLGUIClient::xmlguiBuildDocument
QDomDocument xmlguiBuildDocument() const
Definition: kxmlguiclient.cpp:592
KXMLGUIBuilder
Implements the creation of the GUI (menubar, menus and toolbars) as requested by the GUI factory...
Definition: kxmlguibuilder.h:41
KXMLGUIClient::componentData
virtual KComponentData componentData() const
Definition: kxmlguiclient.cpp:144
KXMLGUIClient::endXMLPlug
void endXMLPlug()
Definition: kxmlguiclient.cpp:739
QStringList
KXMLGUIFactory::readConfigFile
static QString readConfigFile(const QString &filename, const KComponentData &componentData=KComponentData())
Definition: kxmlguifactory.cpp:117
KXMLGUIClient::setXML
virtual void setXML(const QString &document, bool merge=false)
Sets the XML for the part.
Definition: kxmlguiclient.cpp:257
KComponentData::componentName
QString componentName() const
KXMLGUIClient::setComponentData
virtual void setComponentData(const KComponentData &componentData)
Returns true if client was added to super client list.
Definition: kxmlguiclient.cpp:184
kaction.h
KXMLGUIClient::StateChange
Definition: kxmlguiclient.h:263
KXMLGUIFactory
KXMLGUIFactory, together with KXMLGUIClient objects, can be used to create a GUI of container widgets...
Definition: kxmlguifactory.h:65
KStandardDirs::resourceDirs
QStringList resourceDirs(const char *type) const
KActionCollection::setComponentData
void setComponentData(const KComponentData &componentData)
Set the componentData associated with this action collection.
Definition: kactioncollection.cpp:157
KXMLGUIBuilder::setBuilderComponentData
void setBuilderComponentData(const KComponentData &componentData)
Definition: kxmlguibuilder.cpp:397
kxmlguiclient.h
KXMLGUIClient::action
QAction * action(const char *name) const
Retrieves an action of the client by name.
Definition: kxmlguiclient.cpp:115
KXMLGUIClient::parentClient
KXMLGUIClient * parentClient() const
KXMLGUIClients can form a simple child/parent object tree.
Definition: kxmlguiclient.cpp:607
KXMLGUIClient::addStateActionDisabled
void addStateActionDisabled(const QString &state, const QString &action)
Definition: kxmlguiclient.cpp:687
KStandardDirs::locateLocal
static QString locateLocal(const char *type, const QString &filename, const KComponentData &cData=KGlobal::mainComponent())
KXMLGUIClient::plugActionList
void plugActionList(const QString &name, const QList< QAction * > &actionList)
ActionLists are a way for XMLGUI to support dynamic lists of actions.
Definition: kxmlguiclient.cpp:652
kstandarddirs.h
KXMLGUIClient::beginXMLPlug
void beginXMLPlug(QWidget *)
Definition: kxmlguiclient.cpp:732
KActionCollection::addAssociatedWidget
void addAssociatedWidget(QWidget *widget)
Associate all actions in this collection to the given widget, including any actions added after this ...
Definition: kactioncollection.cpp:708
mainComponent
const KComponentData & mainComponent()
kWarning
static QDebug kWarning(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
KXMLGUIClient::~KXMLGUIClient
virtual ~KXMLGUIClient()
Destructs the KXMLGUIClient.
Definition: kxmlguiclient.cpp:93
KXMLGUIClient::domDocument
virtual QDomDocument domDocument() const
Definition: kxmlguiclient.cpp:149
equalstr
static bool equalstr(const QString &a, const QString &b)
Definition: kxmlguiclient.cpp:307
KActionCollection::action
QAction * action(int index) const
Return the QAction* at position "index" in the action collection.
Definition: kactioncollection.cpp:141
KXMLGUIClient::addStateActionEnabled
void addStateActionEnabled(const QString &state, const QString &action)
Definition: kxmlguiclient.cpp:675
KXMLGUIClient::prepareXMLUnplug
void prepareXMLUnplug(QWidget *)
Definition: kxmlguiclient.cpp:743
KXMLGUIClient::virtual_hook
virtual void virtual_hook(int id, void *data)
Definition: kxmlguiclient.cpp:750
KGlobal::staticQString
const QString & staticQString(const char *str)
KStandardDirs::findAllResources
QStringList findAllResources(const char *type, const QString &filter=QString(), SearchOptions options=NoSearchOptions) const
KXMLGUIClient::insertChildClient
void insertChildClient(KXMLGUIClient *child)
Use this method to make a client a child client of another client.
Definition: kxmlguiclient.cpp:612
kcomponentdata.h
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::ReverseStateChange
ReverseStateChange
Definition: kxmlguiclient.h:262
KXMLGUIClient::findMostRecentXMLFile
static QString findMostRecentXMLFile(const QStringList &files, QString &doc)
Definition: kxmlguiclient.cpp:668
kFatal
static QDebug kFatal(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
KXMLGUIClient::unplugActionList
void unplugActionList(const QString &name)
Unplugs the action list name from the XMLGUI.
Definition: kxmlguiclient.cpp:660
KComponentData
KAuthorized::authorizeKAction
bool authorizeKAction(const QString &action)
QAction
QMap< QString, KXMLGUIClient::StateChange >
QList< KXMLGUIClient * >
KXMLGUIClient::setXMLGUIBuildDocument
void setXMLGUIBuildDocument(const QDomDocument &doc)
Definition: kxmlguiclient.cpp:587
KComponentData::dirs
KStandardDirs * dirs() const
KXMLGUIClient::KXMLGUIClient
KXMLGUIClient()
Constructs a KXMLGUIClient which can be used with a KXMLGUIFactory to create a GUI from actions and a...
Definition: kxmlguiclient.cpp:82
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:49:16 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
  • kjsembed
  •   WTF
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Nepomuk-Core
  • 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