00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "kxmlguifactory.h"
00022 #include "kxmlguifactory_p.h"
00023 #include "kxmlguiclient.h"
00024 #include "kxmlguibuilder.h"
00025
00026 #include <assert.h>
00027
00028 #include <QtCore/QDir>
00029 #include <QtXml/QDomDocument>
00030 #include <QtCore/QFile>
00031 #include <QtCore/QTextIStream>
00032 #include <QtGui/QWidget>
00033 #include <QtCore/QDate>
00034 #include <QtCore/QVariant>
00035 #include <QTextCodec>
00036
00037 #include <kdebug.h>
00038 #include <kcomponentdata.h>
00039 #include <kglobal.h>
00040 #include <kshortcut.h>
00041 #include <kstandarddirs.h>
00042
00043 #include "kaction.h"
00044 #include "kshortcutsdialog.h"
00045 #include "kactioncollection.h"
00046
00047 using namespace KXMLGUI;
00048
00049 class KXMLGUIFactoryPrivate : public BuildState
00050 {
00051 public:
00052 enum ShortcutOption { SetActiveShortcut = 1, SetDefaultShortcut = 2};
00053
00054 KXMLGUIFactoryPrivate()
00055 {
00056 static const QString &defaultMergingName = KGlobal::staticQString( "<default>" );
00057 static const QString &actionList = KGlobal::staticQString( "actionlist" );
00058 static const QString &name = KGlobal::staticQString( "name" );
00059
00060 m_rootNode = new ContainerNode( 0L, QString(), 0L );
00061 m_defaultMergingName = defaultMergingName;
00062 tagActionList = actionList;
00063 attrName = name;
00064 }
00065 ~KXMLGUIFactoryPrivate()
00066 {
00067 delete m_rootNode;
00068 }
00069
00070 void pushState()
00071 {
00072 m_stateStack.push( *this );
00073 }
00074
00075 void popState()
00076 {
00077 BuildState::operator=( m_stateStack.pop() );
00078 }
00079
00080 bool emptyState() const { return m_stateStack.isEmpty(); }
00081
00082 QWidget *findRecursive( KXMLGUI::ContainerNode *node, bool tag );
00083 QList<QWidget*> findRecursive( KXMLGUI::ContainerNode *node, const QString &tagName );
00084 void applyActionProperties( const QDomElement &element,
00085 ShortcutOption shortcutOption = KXMLGUIFactoryPrivate::SetActiveShortcut );
00086 void configureAction( QAction *action, const QDomNamedNodeMap &attributes,
00087 ShortcutOption shortcutOption = KXMLGUIFactoryPrivate::SetActiveShortcut );
00088 void configureAction( QAction *action, const QDomAttr &attribute,
00089 ShortcutOption shortcutOption = KXMLGUIFactoryPrivate::SetActiveShortcut );
00090
00091 QDomDocument shortcutSchemeDoc(KXMLGUIClient *client);
00092 void applyShortcutScheme(KXMLGUIClient *client, QDomDocument scheme);
00093 void refreshActionProperties(KXMLGUIClient *client, QDomDocument doc);
00094 void saveDefaultActionProperties(KXMLGUIClient *client);
00095
00096 ContainerNode *m_rootNode;
00097
00098 QString m_defaultMergingName;
00099
00100
00101
00102
00103 QString m_containerName;
00104
00105
00106
00107
00108 QList<KXMLGUIClient*> m_clients;
00109
00110 QString tagActionList;
00111
00112 QString attrName;
00113
00114 BuildStateStack m_stateStack;
00115 };
00116
00117 QString KXMLGUIFactory::readConfigFile( const QString &filename, const KComponentData &_componentData )
00118 {
00119 KComponentData componentData = _componentData.isValid() ? _componentData : KGlobal::mainComponent();
00120 QString xml_file;
00121
00122 if (!QDir::isRelativePath(filename))
00123 xml_file = filename;
00124 else
00125 {
00126 xml_file = KStandardDirs::locate("data", componentData.componentName() + '/' + filename);
00127 if ( !QFile::exists( xml_file ) )
00128 xml_file = KStandardDirs::locate( "data", filename );
00129 }
00130
00131 QFile file( xml_file );
00132 if ( xml_file.isEmpty() || !file.open( QIODevice::ReadOnly ) )
00133 {
00134 kError(240) << "No such XML file" << filename;
00135 return QString();
00136 }
00137
00138 QByteArray buffer(file.readAll());
00139 return QString::fromUtf8(buffer.constData(), buffer.size());
00140 }
00141
00142 bool KXMLGUIFactory::saveConfigFile( const QDomDocument& doc,
00143 const QString& filename, const KComponentData &_componentData )
00144 {
00145 KComponentData componentData = _componentData.isValid() ? _componentData : KGlobal::mainComponent();
00146 QString xml_file(filename);
00147
00148 if (QDir::isRelativePath(xml_file))
00149 xml_file = KStandardDirs::locateLocal("data", componentData.componentName() + '/' + filename);
00150
00151 QFile file( xml_file );
00152 if ( xml_file.isEmpty() || !file.open( QIODevice::WriteOnly ) )
00153 {
00154 kError(240) << "Could not write to" << filename;
00155 return false;
00156 }
00157
00158
00159 QTextStream ts(&file);
00160 ts.setCodec( QTextCodec::codecForName( "UTF-8" ) );
00161 ts << doc;
00162
00163 file.close();
00164 return true;
00165 }
00166
00170 static void removeDOMComments( QDomNode &node )
00171 {
00172 QDomNode n = node.firstChild();
00173 while ( !n.isNull() )
00174 {
00175 if ( n.nodeType() == QDomNode::CommentNode )
00176 {
00177 QDomNode tmp = n;
00178 n = n.nextSibling();
00179 node.removeChild( tmp );
00180 }
00181 else
00182 {
00183 QDomNode tmp = n;
00184 n = n.nextSibling();
00185 removeDOMComments( tmp );
00186 }
00187 }
00188 }
00189
00190 KXMLGUIFactory::KXMLGUIFactory( KXMLGUIBuilder *builder, QObject *parent )
00191 : QObject( parent ),d(new KXMLGUIFactoryPrivate)
00192 {
00193 d->builder = builder;
00194 d->guiClient = 0;
00195 if ( d->builder )
00196 {
00197 d->builderContainerTags = d->builder->containerTags();
00198 d->builderCustomTags = d->builder->customTags();
00199 }
00200 }
00201
00202 KXMLGUIFactory::~KXMLGUIFactory()
00203 {
00204 delete d;
00205 }
00206
00207 void KXMLGUIFactory::addClient( KXMLGUIClient *client )
00208 {
00209
00210 if ( client->factory() ) {
00211 if ( client->factory() == this )
00212 return;
00213 else
00214 client->factory()->removeClient( client );
00215 }
00216
00217 if (d->emptyState())
00218 emit makingChanges(true);
00219 d->pushState();
00220
00221
00222
00223 d->guiClient = client;
00224
00225
00226 if ( !d->m_clients.contains( client ) )
00227 d->m_clients.append( client );
00228 else
00229 kDebug(260) << "XMLGUI client already added " << client;
00230
00231
00232
00233
00234 client->beginXMLPlug( d->builder->widget() );
00235
00236
00237
00238
00239 QDomDocument doc = client->xmlguiBuildDocument();
00240 if ( doc.documentElement().isNull() )
00241 doc = client->domDocument();
00242
00243 QDomElement docElement = doc.documentElement();
00244
00245 d->m_rootNode->index = -1;
00246
00247
00248
00249 d->clientName = docElement.attribute( d->attrName );
00250 d->clientBuilder = client->clientBuilder();
00251
00252 if ( d->clientBuilder )
00253 {
00254 d->clientBuilderContainerTags = d->clientBuilder->containerTags();
00255 d->clientBuilderCustomTags = d->clientBuilder->customTags();
00256 }
00257 else
00258 {
00259 d->clientBuilderContainerTags.clear();
00260 d->clientBuilderCustomTags.clear();
00261 }
00262
00263
00264 d->saveDefaultActionProperties(client);
00265 d->refreshActionProperties(client, doc);
00266
00267 BuildHelper( *d, d->m_rootNode ).build( docElement );
00268
00269
00270 client->setFactory( this );
00271
00272
00273
00274
00275
00276 d->builder->finalizeGUI( d->guiClient );
00277
00278
00279 d->BuildState::reset();
00280
00281 client->endXMLPlug();
00282
00283 d->popState();
00284
00285 emit clientAdded( client );
00286
00287
00288 foreach (KXMLGUIClient *child, client->childClients())
00289 addClient( child );
00290
00291 if (d->emptyState())
00292 emit makingChanges(false);
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305 }
00306
00307 void KXMLGUIFactory::refreshActionProperties()
00308 {
00309 foreach (KXMLGUIClient *client, d->m_clients)
00310 {
00311 d->guiClient = client;
00312 QDomDocument doc = client->xmlguiBuildDocument();
00313 if ( doc.documentElement().isNull() )
00314 {
00315 client->reloadXML();
00316 doc = client->domDocument();
00317 }
00318 d->refreshActionProperties(client, doc);
00319 }
00320 d->guiClient = 0;
00321 }
00322
00323 void KXMLGUIFactoryPrivate::refreshActionProperties(KXMLGUIClient *client, QDomDocument doc)
00324 {
00325
00326 QDomDocument scheme = shortcutSchemeDoc(client);
00327 applyShortcutScheme(client, scheme);
00328
00329
00330 QDomElement actionPropElement = KXMLGUIFactory::actionPropertiesElement(doc);
00331 if (actionPropElement.childNodes().isEmpty())
00332 doc.documentElement().removeChild(actionPropElement);
00333
00334 if ( !actionPropElement.isNull() )
00335 applyActionProperties( actionPropElement );
00336 }
00337
00338 void KXMLGUIFactoryPrivate::saveDefaultActionProperties(KXMLGUIClient *client)
00339 {
00340
00341
00342
00343 foreach (QAction *action, client->actionCollection()->actions())
00344 {
00345
00346 if (action->property("_k_DefaultShortcut").isValid()) continue;
00347
00348 if (KAction* kaction = qobject_cast<KAction*>(action))
00349 {
00350
00351 KShortcut defaultShortcut = kaction->shortcut(KAction::DefaultShortcut);
00352 KShortcut activeShortcut = kaction->shortcut(KAction::ActiveShortcut);
00353
00354
00355
00356
00357
00358 if ((!activeShortcut.isEmpty()) && defaultShortcut.isEmpty())
00359 {
00360 kError(240) << "Shortcut for KAction " << kaction->objectName() << kaction->text() << "set with QShortcut::setShortcut()! See KAction documentation.";
00361 kaction->setProperty("_k_DefaultShortcut", activeShortcut);
00362 }
00363 else
00364 {
00365 kaction->setProperty("_k_DefaultShortcut", defaultShortcut);
00366 }
00367 }
00368 else
00369 {
00370
00371 kError(240) << "Attempt to use QAction" << action->objectName() << "with KXMLGUIFactory!";
00372 action->setProperty("_k_DefaultShortcut", KShortcut());
00373 }
00374
00375 }
00376 }
00377
00378 void KXMLGUIFactory::changeShortcutScheme(const QString &scheme)
00379 {
00380 kDebug(260) << "Changing shortcut scheme to" << scheme;
00381 KConfigGroup cg = KGlobal::config()->group( "Shortcut Schemes" );
00382 cg.writeEntry("Current Scheme", scheme);
00383
00384 refreshActionProperties();
00385 }
00386
00387 void KXMLGUIFactory::removeClient( KXMLGUIClient *client )
00388 {
00389
00390
00391
00392 if ( !client || client->factory() != this )
00393 return;
00394
00395 if (d->emptyState())
00396 emit makingChanges(true);
00397
00398
00399 d->m_clients.removeAll( client );
00400
00401
00402
00403 const QList<KXMLGUIClient*> childClients(client->childClients());
00404 foreach (KXMLGUIClient *child, childClients)
00405 removeClient(child);
00406
00407
00408
00409 d->pushState();
00410
00411
00412
00413 d->guiClient = client;
00414 d->clientName = client->domDocument().documentElement().attribute( d->attrName );
00415 d->clientBuilder = client->clientBuilder();
00416
00417 client->setFactory( 0L );
00418
00419
00420
00421
00422 QDomDocument doc = client->xmlguiBuildDocument();
00423 if ( doc.documentElement().isNull() )
00424 {
00425 doc = client->domDocument().cloneNode( true ).toDocument();
00426 client->setXMLGUIBuildDocument( doc );
00427 }
00428
00429 d->m_rootNode->destruct( doc.documentElement(), *d );
00430
00431
00432 d->BuildState::reset();
00433
00434
00435 client->prepareXMLUnplug( d->builder->widget() );
00436
00437 d->popState();
00438
00439 if (d->emptyState())
00440 emit makingChanges(false);
00441
00442 emit clientRemoved( client );
00443 }
00444
00445 QList<KXMLGUIClient*> KXMLGUIFactory::clients() const
00446 {
00447 return d->m_clients;
00448 }
00449
00450 QWidget *KXMLGUIFactory::container( const QString &containerName, KXMLGUIClient *client,
00451 bool useTagName )
00452 {
00453 d->pushState();
00454 d->m_containerName = containerName;
00455 d->guiClient = client;
00456
00457 QWidget *result = d->findRecursive( d->m_rootNode, useTagName );
00458
00459 d->guiClient = 0L;
00460 d->m_containerName.clear();
00461
00462 d->popState();
00463
00464 return result;
00465 }
00466
00467 QList<QWidget*> KXMLGUIFactory::containers( const QString &tagName )
00468 {
00469 return d->findRecursive( d->m_rootNode, tagName );
00470 }
00471
00472 void KXMLGUIFactory::reset()
00473 {
00474 d->m_rootNode->reset();
00475
00476 d->m_rootNode->clearChildren();
00477 }
00478
00479 void KXMLGUIFactory::resetContainer( const QString &containerName, bool useTagName )
00480 {
00481 if ( containerName.isEmpty() )
00482 return;
00483
00484 ContainerNode *container = d->m_rootNode->findContainer( containerName, useTagName );
00485
00486 if ( !container )
00487 return;
00488
00489 ContainerNode *parent = container->parent;
00490 if ( !parent )
00491 return;
00492
00493
00494
00495 parent->removeChild( container );
00496 }
00497
00498 QWidget *KXMLGUIFactoryPrivate::findRecursive( KXMLGUI::ContainerNode *node, bool tag )
00499 {
00500 if ( ( ( !tag && node->name == m_containerName ) ||
00501 ( tag && node->tagName == m_containerName ) ) &&
00502 ( !guiClient || node->client == guiClient ) )
00503 return node->container;
00504
00505 foreach (ContainerNode* child, node->children)
00506 {
00507 QWidget *cont = findRecursive( child, tag );
00508 if ( cont )
00509 return cont;
00510 }
00511
00512 return 0L;
00513 }
00514
00515
00516 static inline bool equals(const QString& str1, const char* str2)
00517 {
00518 return str1.compare(QLatin1String(str2), Qt::CaseInsensitive) == 0;
00519 }
00520 static inline bool equals(const QString& str1, const QString& str2)
00521 {
00522 return str1.compare(str2, Qt::CaseInsensitive) == 0;
00523 }
00524
00525
00526 QList<QWidget*> KXMLGUIFactoryPrivate::findRecursive( KXMLGUI::ContainerNode *node,
00527 const QString &tagName )
00528 {
00529 QList<QWidget*> res;
00530
00531 if ( equals(node->tagName, tagName) )
00532 res.append( node->container );
00533
00534 foreach (KXMLGUI::ContainerNode* child, node->children)
00535 res << findRecursive( child, tagName );
00536
00537 return res;
00538 }
00539
00540 void KXMLGUIFactory::plugActionList( KXMLGUIClient *client, const QString &name,
00541 const QList<QAction*> &actionList )
00542 {
00543 d->pushState();
00544 d->guiClient = client;
00545 d->actionListName = name;
00546 d->actionList = actionList;
00547 d->clientName = client->domDocument().documentElement().attribute( d->attrName );
00548
00549 d->m_rootNode->plugActionList( *d );
00550
00551 d->BuildState::reset();
00552 d->popState();
00553 }
00554
00555 void KXMLGUIFactory::unplugActionList( KXMLGUIClient *client, const QString &name )
00556 {
00557 d->pushState();
00558 d->guiClient = client;
00559 d->actionListName = name;
00560 d->clientName = client->domDocument().documentElement().attribute( d->attrName );
00561
00562 d->m_rootNode->unplugActionList( *d );
00563
00564 d->BuildState::reset();
00565 d->popState();
00566 }
00567
00568 void KXMLGUIFactoryPrivate::applyActionProperties( const QDomElement &actionPropElement,
00569 ShortcutOption shortcutOption )
00570 {
00571 for (QDomNode n = actionPropElement.firstChild();
00572 !n.isNull(); n = n.nextSibling() )
00573 {
00574 QDomElement e = n.toElement();
00575 if ( !equals(e.tagName(), "action") )
00576 continue;
00577
00578 QAction *action = guiClient->action( e );
00579 if ( !action )
00580 continue;
00581
00582 configureAction( action, e.attributes(), shortcutOption );
00583 }
00584 }
00585
00586 void KXMLGUIFactoryPrivate::configureAction( QAction *action, const QDomNamedNodeMap &attributes,
00587 ShortcutOption shortcutOption )
00588 {
00589 for ( uint i = 0; i < attributes.length(); i++ )
00590 {
00591 QDomAttr attr = attributes.item( i ).toAttr();
00592 if ( attr.isNull() )
00593 continue;
00594
00595 configureAction( action, attr, shortcutOption );
00596 }
00597 }
00598
00599 void KXMLGUIFactoryPrivate::configureAction( QAction *action, const QDomAttr &attribute,
00600 ShortcutOption shortcutOption )
00601 {
00602 static const QString &attrShortcut = KGlobal::staticQString( "shortcut" );
00603
00604 QString attrName = attribute.name();
00605
00606 if ( equals(attrName, "accel") )
00607 attrName = attrShortcut;
00608
00609
00610 if ( equals(attrName, "name") )
00611 return;
00612
00613 if ( equals(attrName, "icon") ) {
00614 action->setIcon( KIcon( attribute.value() ) );
00615 return;
00616 }
00617
00618 QVariant propertyValue;
00619
00620 QVariant::Type propertyType = action->property( attrName.toLatin1() ).type();
00621
00622 if ( propertyType == QVariant::Int ) {
00623 propertyValue = QVariant( attribute.value().toInt() );
00624 } else if ( propertyType == QVariant::UInt ) {
00625 propertyValue = QVariant( attribute.value().toUInt() );
00626 } else if ( propertyType == QVariant::UserType && action->property( attrName.toLatin1() ).userType() == qMetaTypeId<KShortcut>() ) {
00627
00628 if (KAction* ka = qobject_cast<KAction*>(action)) {
00629 if (attrName=="globalShortcut") {
00630 ka->setGlobalShortcut(KShortcut(attribute.value()), KAction::ActiveShortcut);
00631 } else {
00632 ka->setShortcut(KShortcut(attribute.value()), KAction::ActiveShortcut);
00633 }
00634 if (shortcutOption & KXMLGUIFactoryPrivate::SetDefaultShortcut)
00635 ka->setShortcut(KShortcut(attribute.value()), KAction::DefaultShortcut);
00636 return;
00637 }
00638 propertyValue = KShortcut( attribute.value() );
00639 } else {
00640 propertyValue = QVariant( attribute.value() );
00641 }
00642 if (!action->setProperty( attrName.toLatin1(), propertyValue )) {
00643 kWarning() << "Error: Unknown action property " << attrName << " will be ignored!";
00644 }
00645 }
00646
00647 QDomDocument KXMLGUIFactoryPrivate::shortcutSchemeDoc(KXMLGUIClient *client)
00648 {
00649
00650 KConfigGroup cg = KGlobal::config()->group( "Shortcut Schemes" );
00651 QString schemeName = cg.readEntry("Current Scheme", "Default");
00652
00653 QDomDocument doc;
00654 if (schemeName != "Default")
00655 {
00656
00657
00658 QString schemeFileName = KStandardDirs::locateLocal("data",
00659 client->componentData().componentName() + '/' +
00660 client->componentData().componentName() + schemeName.toLower() + "shortcuts.rc" );
00661
00662 QFile schemeFile(schemeFileName);
00663 if (schemeFile.open(QIODevice::ReadOnly))
00664 {
00665
00666 doc.setContent(&schemeFile);
00667 schemeFile.close();
00668 }
00669 }
00670 return doc;
00671 }
00672
00673 void KXMLGUIFactoryPrivate::applyShortcutScheme(KXMLGUIClient *client, QDomDocument scheme)
00674 {
00675 static const QString &actionPropElementName = KGlobal::staticQString( "ActionProperties" );
00676
00677 KConfigGroup cg = KGlobal::config()->group( "Shortcut Schemes" );
00678 QString schemeName = cg.readEntry("Current Scheme", "Default");
00679
00680
00681 if (schemeName != "Default") {
00682 foreach (QAction *action, client->actionCollection()->actions())
00683 {
00684 if (KAction *kaction = qobject_cast<KAction*>(action))
00685 {
00686 kaction->setShortcut(KShortcut(), KAction::ActiveShortcut);
00687
00688 kaction->setShortcut(KShortcut(), KAction::DefaultShortcut);
00689 }
00690 else
00691 action->setProperty("shortcut", KShortcut());
00692 }
00693 } else {
00694
00695 foreach (QAction *action, client->actionCollection()->actions())
00696 {
00697 if (KAction *kaction = qobject_cast<KAction*>(action))
00698 {
00699 QVariant savedDefaultShortcut = kaction->property("_k_DefaultShortcut");
00700 if (savedDefaultShortcut.isValid())
00701 {
00702 KShortcut shortcut = savedDefaultShortcut.value<KShortcut>();
00703 kaction->setShortcut(shortcut, KAction::ActiveShortcut);
00704 kaction->setShortcut(shortcut, KAction::DefaultShortcut);
00705 continue;
00706 }
00707 }
00708 action->setProperty("shortcut", KShortcut());
00709 }
00710 }
00711
00712 if (scheme.isNull())
00713 return;
00714
00715 QDomElement docElement = scheme.documentElement();
00716 QDomElement actionPropElement = docElement.namedItem( actionPropElementName ).toElement();
00717
00718
00719 if (!actionPropElement.isNull())
00720 {
00721 kDebug(260) << "Applying shortcut scheme for XMLGUI client" << client->componentData().componentName();
00722
00723
00724 applyActionProperties(actionPropElement, KXMLGUIFactoryPrivate::SetDefaultShortcut);
00725 }
00726 else
00727 kDebug(260) << "Invalid shortcut scheme file";
00728 }
00729
00730 int KXMLGUIFactory::configureShortcuts(bool letterCutsOk , bool bSaveSettings )
00731 {
00732 KShortcutsDialog dlg(KShortcutsEditor::AllActions,
00733 letterCutsOk ? KShortcutsEditor::LetterShortcutsAllowed : KShortcutsEditor::LetterShortcutsDisallowed,
00734 qobject_cast<QWidget*>(parent()));
00735 foreach (KXMLGUIClient *client, d->m_clients)
00736 {
00737 if(client && !client->xmlFile().isEmpty())
00738 dlg.addCollection( client->actionCollection() );
00739 }
00740 return dlg.configure(bSaveSettings);
00741 }
00742
00743 QDomElement KXMLGUIFactory::actionPropertiesElement( QDomDocument& doc )
00744 {
00745 KConfigGroup cg = KGlobal::config()->group( "Shortcut Schemes" );
00746 QString schemeName = cg.readEntry("Current Scheme", "Default");
00747
00748 const QString tagActionProp = QLatin1String("ActionProperties");
00749
00750 QDomElement elem;
00751 QDomNode it = doc.documentElement().firstChild();
00752 for( ; !it.isNull(); it = it.nextSibling() ) {
00753 QDomElement e = it.toElement();
00754 if( ((e.tagName() == tagActionProp) || (e.tagName() == tagActionProp.toLower()))
00755 && (e.attribute("scheme", "Default") == schemeName) ) {
00756 elem = e;
00757 break;
00758 }
00759 }
00760
00761
00762 if( elem.isNull() ) {
00763 elem = doc.createElement( tagActionProp );
00764 elem.setAttribute( "scheme", schemeName );
00765 doc.documentElement().appendChild( elem );
00766 }
00767 return elem;
00768 }
00769
00770 QDomElement KXMLGUIFactory::findActionByName( QDomElement& elem, const QString& sName, bool create )
00771 {
00772 static const QString& attrName = KGlobal::staticQString( "name" );
00773 static const QString& tagAction = KGlobal::staticQString( "Action" );
00774 for( QDomNode it = elem.firstChild(); !it.isNull(); it = it.nextSibling() ) {
00775 QDomElement e = it.toElement();
00776 if( e.attribute( attrName ) == sName )
00777 return e;
00778 }
00779
00780 if( create ) {
00781 QDomElement act_elem = elem.ownerDocument().createElement( tagAction );
00782 act_elem.setAttribute( attrName, sName );
00783 elem.appendChild( act_elem );
00784 return act_elem;
00785 }
00786 return QDomElement();
00787 }
00788
00789 #include "kxmlguifactory.moc"
00790
00791
00792