00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "kxmlguiclient.h"
00021 #include "kxmlguifactory.h"
00022 #include "kxmlguibuilder.h"
00023
00024 #include <qdir.h>
00025 #include <qfile.h>
00026 #include <qdom.h>
00027 #include <qtextstream.h>
00028 #include <qregexp.h>
00029 #include <qguardedptr.h>
00030
00031 #include <kinstance.h>
00032 #include <kstandarddirs.h>
00033 #include <kdebug.h>
00034 #include <kaction.h>
00035 #include <kapplication.h>
00036
00037 #include <assert.h>
00038
00039 class KXMLGUIClientPrivate
00040 {
00041 public:
00042 KXMLGUIClientPrivate()
00043 {
00044 m_instance = KGlobal::instance();
00045 m_parent = 0L;
00046 m_builder = 0L;
00047 m_actionCollection = 0;
00048 }
00049 ~KXMLGUIClientPrivate()
00050 {
00051 }
00052
00053 KInstance *m_instance;
00054
00055 QDomDocument m_doc;
00056 KActionCollection *m_actionCollection;
00057 QDomDocument m_buildDocument;
00058 QGuardedPtr<KXMLGUIFactory> m_factory;
00059 KXMLGUIClient *m_parent;
00060
00061 QPtrList<KXMLGUIClient> m_children;
00062 KXMLGUIBuilder *m_builder;
00063 QString m_xmlFile;
00064 QString m_localXMLFile;
00065 };
00066
00067 KXMLGUIClient::KXMLGUIClient()
00068 {
00069 d = new KXMLGUIClientPrivate;
00070 }
00071
00072 KXMLGUIClient::KXMLGUIClient( KXMLGUIClient *parent )
00073 {
00074 d = new KXMLGUIClientPrivate;
00075 parent->insertChildClient( this );
00076 }
00077
00078 KXMLGUIClient::~KXMLGUIClient()
00079 {
00080 if ( d->m_parent )
00081 d->m_parent->removeChildClient( this );
00082
00083 QPtrListIterator<KXMLGUIClient> it( d->m_children );
00084 for ( ; it.current(); ++it ) {
00085 assert( it.current()->d->m_parent == this );
00086 it.current()->d->m_parent = 0;
00087 }
00088
00089 delete d->m_actionCollection;
00090 delete d;
00091 }
00092
00093 KAction *KXMLGUIClient::action( const char *name ) const
00094 {
00095 KAction* act = actionCollection()->action( name );
00096 if ( !act ) {
00097 QPtrListIterator<KXMLGUIClient> childIt( d->m_children );
00098 for (; childIt.current(); ++childIt ) {
00099 act = childIt.current()->actionCollection()->action( name );
00100 if ( act )
00101 break;
00102 }
00103 }
00104 return act;
00105 }
00106
00107 KActionCollection *KXMLGUIClient::actionCollection() const
00108 {
00109 if ( !d->m_actionCollection )
00110 d->m_actionCollection = new KActionCollection( 0, 0,
00111 "KXMLGUILClient-KActionCollection" );
00112 return d->m_actionCollection;
00113 }
00114
00115 KAction *KXMLGUIClient::action( const QDomElement &element ) const
00116 {
00117 static const QString &attrName = KGlobal::staticQString( "name" );
00118 return actionCollection()->action( element.attribute( attrName ).latin1() );
00119 }
00120
00121 KInstance *KXMLGUIClient::instance() const
00122 {
00123 return d->m_instance;
00124 }
00125
00126 QDomDocument KXMLGUIClient::domDocument() const
00127 {
00128 return d->m_doc;
00129 }
00130
00131 QString KXMLGUIClient::xmlFile() const
00132 {
00133 return d->m_xmlFile;
00134 }
00135
00136 QString KXMLGUIClient::localXMLFile() const
00137 {
00138 if ( !d->m_localXMLFile.isEmpty() )
00139 return d->m_localXMLFile;
00140
00141 if ( d->m_xmlFile[0] == '/' )
00142 return QString::null;
00143
00144 return locateLocal( "data", QString::fromLatin1( instance()->instanceName() + '/' ) + d->m_xmlFile );
00145 }
00146
00147
00148 void KXMLGUIClient::reloadXML()
00149 {
00150 QString file( xmlFile() );
00151 if ( !file.isEmpty() )
00152 setXMLFile( file );
00153 }
00154
00155 void KXMLGUIClient::setInstance( KInstance *instance )
00156 {
00157 d->m_instance = instance;
00158 actionCollection()->setInstance( instance );
00159 if ( d->m_builder )
00160 d->m_builder->setBuilderClient( this );
00161 }
00162
00163 void KXMLGUIClient::setXMLFile( const QString& _file, bool merge, bool setXMLDoc )
00164 {
00165
00166 if ( !_file.isNull() ) {
00167 d->m_xmlFile = _file;
00168 actionCollection()->setXMLFile( _file );
00169 }
00170
00171 if ( !setXMLDoc )
00172 return;
00173
00174 QString file = _file;
00175 if ( file[0] != '/' )
00176 {
00177 QString doc;
00178
00179 QString filter = QString::fromLatin1( instance()->instanceName() + '/' ) + _file;
00180
00181 QStringList allFiles = instance()->dirs()->findAllResources( "data", filter ) + instance()->dirs()->findAllResources( "data", _file );
00182
00183 file = findMostRecentXMLFile( allFiles, doc );
00184
00185 if ( file.isEmpty() )
00186 {
00187
00188
00189
00190
00191
00192
00193 if ( !_file.isEmpty() )
00194 kdWarning() << "KXMLGUIClient::setXMLFile: cannot find .rc file " << _file << endl;
00195
00196 setXML( QString::null, true );
00197 return;
00198 }
00199 else if ( !doc.isEmpty() )
00200 {
00201 setXML( doc, merge );
00202 return;
00203 }
00204 }
00205
00206 QString xml = KXMLGUIFactory::readConfigFile( file );
00207 setXML( xml, merge );
00208 }
00209
00210 void KXMLGUIClient::setLocalXMLFile( const QString &file )
00211 {
00212 d->m_localXMLFile = file;
00213 }
00214
00215 void KXMLGUIClient::setXML( const QString &document, bool merge )
00216 {
00217 QDomDocument doc;
00218 doc.setContent( document );
00219 setDOMDocument( doc, merge );
00220 }
00221
00222 void KXMLGUIClient::setDOMDocument( const QDomDocument &document, bool merge )
00223 {
00224 if ( merge )
00225 {
00226 QDomElement base = d->m_doc.documentElement();
00227
00228 QDomElement e = document.documentElement();
00229 KXMLGUIFactory::removeDOMComments( e );
00230
00231
00232 mergeXML(base, e, actionCollection());
00233
00234
00235
00236 base = d->m_doc.documentElement();
00237
00238
00239 if ( base.isNull() )
00240 d->m_doc = document;
00241 }
00242 else
00243 {
00244 d->m_doc = document;
00245 KXMLGUIFactory::removeDOMComments( d->m_doc );
00246 }
00247
00248 setXMLGUIBuildDocument( QDomDocument() );
00249 }
00250
00251 bool KXMLGUIClient::mergeXML( QDomElement &base, const QDomElement &additive, KActionCollection *actionCollection )
00252 {
00253 static const QString &tagAction = KGlobal::staticQString( "Action" );
00254 static const QString &tagMerge = KGlobal::staticQString( "Merge" );
00255 static const QString &tagSeparator = KGlobal::staticQString( "Separator" );
00256 static const QString &attrName = KGlobal::staticQString( "name" );
00257 static const QString &attrAppend = KGlobal::staticQString( "append" );
00258 static const QString &attrWeakSeparator = KGlobal::staticQString( "weakSeparator" );
00259 static const QString &tagMergeLocal = KGlobal::staticQString( "MergeLocal" );
00260 static const QString &tagText = KGlobal::staticQString( "text" );
00261 static const QString &attrAlreadyVisited = KGlobal::staticQString( "alreadyVisited" );
00262 static const QString &attrNoMerge = KGlobal::staticQString( "noMerge" );
00263 static const QString &attrOne = KGlobal::staticQString( "1" );
00264
00265
00266
00267
00268
00269
00270 if ( additive.attribute(attrNoMerge) == attrOne )
00271 {
00272 base.parentNode().replaceChild(additive, base);
00273 return true;
00274 }
00275
00276 QString tag;
00277
00278 QDomElement e = base.firstChild().toElement();
00279
00280 while ( !e.isNull() )
00281 {
00282 tag = e.tagName();
00283
00284
00285
00286 if ( tag == tagAction )
00287 {
00288 QCString name = e.attribute( attrName ).utf8();
00289 if ( !actionCollection->action( name ) ||
00290 (kapp && !kapp->authorizeKAction(name)))
00291 {
00292
00293 QDomElement oldChild = e;
00294 e = e.nextSibling().toElement();
00295 base.removeChild( oldChild );
00296 continue;
00297 }
00298 }
00299
00300
00301
00302 else if ( tag == tagSeparator )
00303 {
00304 e.setAttribute( attrWeakSeparator, (uint)1 );
00305
00306
00307
00308
00309 QDomElement prev = e.previousSibling().toElement();
00310 if ( prev.isNull() ||
00311 ( prev.tagName() == tagSeparator && !prev.attribute( attrWeakSeparator ).isNull() ) ||
00312 ( prev.tagName() == tagText ) )
00313 {
00314
00315 QDomElement oldChild = e;
00316 e = e.nextSibling().toElement();
00317 base.removeChild( oldChild );
00318 continue;
00319 }
00320 }
00321
00322
00323
00324
00325 else if ( tag == tagMergeLocal )
00326 {
00327 QDomElement currElement = e;
00328
00329
00330
00331 e = e.nextSibling().toElement();
00332
00333 QDomElement it = additive.firstChild().toElement();
00334 while ( !it.isNull() )
00335 {
00336 QDomElement newChild = it;
00337
00338 it = it.nextSibling().toElement();
00339
00340 if ( newChild.tagName() == tagText )
00341 continue;
00342
00343 if ( newChild.attribute( attrAlreadyVisited ) == attrOne )
00344 continue;
00345
00346 QString itAppend( newChild.attribute( attrAppend ) );
00347 QString elemName( currElement.attribute( attrName ) );
00348
00349 if ( ( itAppend.isNull() && elemName.isEmpty() ) ||
00350 ( itAppend == elemName ) )
00351 {
00352
00353
00354
00355 QDomElement matchingElement = findMatchingElement( newChild, base );
00356 if ( matchingElement.isNull() || newChild.tagName() == tagSeparator )
00357 base.insertBefore( newChild, currElement );
00358 }
00359 }
00360
00361 base.removeChild( currElement );
00362 continue;
00363 }
00364
00365
00366
00367
00368
00369 else if ( tag != tagMerge )
00370 {
00371
00372 if ( tag == tagText )
00373 {
00374 e = e.nextSibling().toElement();
00375 continue;
00376 }
00377
00378 QDomElement matchingElement = findMatchingElement( e, additive );
00379
00380 QDomElement currElement = e;
00381 e = e.nextSibling().toElement();
00382
00383 if ( !matchingElement.isNull() )
00384 {
00385 matchingElement.setAttribute( attrAlreadyVisited, (uint)1 );
00386
00387 if ( mergeXML( currElement, matchingElement, actionCollection ) )
00388 {
00389 base.removeChild( currElement );
00390 continue;
00391 }
00392
00393
00394 QDomNamedNodeMap attribs = matchingElement.attributes();
00395 for(uint i = 0; i < attribs.count(); i++)
00396 {
00397 QDomNode node = attribs.item(i);
00398 currElement.setAttribute(node.nodeName(), node.nodeValue());
00399 }
00400
00401 continue;
00402 }
00403 else
00404 {
00405
00406
00407
00408
00409
00410 if ( mergeXML( currElement, QDomElement(), actionCollection ) )
00411 base.removeChild( currElement );
00412 continue;
00413 }
00414 }
00415
00416
00417 e = e.nextSibling().toElement();
00418 }
00419
00420
00421
00422 e = additive.firstChild().toElement();
00423 while ( !e.isNull() )
00424 {
00425 QDomElement matchingElement = findMatchingElement( e, base );
00426
00427 if ( matchingElement.isNull() )
00428 {
00429 QDomElement newChild = e;
00430 e = e.nextSibling().toElement();
00431 base.appendChild( newChild );
00432 }
00433 else
00434 e = e.nextSibling().toElement();
00435 }
00436
00437
00438
00439 QDomElement last = base.lastChild().toElement();
00440 if ( (last.tagName() == tagSeparator) && (!last.attribute( attrWeakSeparator ).isNull()) )
00441 {
00442 base.removeChild( base.lastChild() );
00443 }
00444
00445
00446
00447
00448 bool deleteMe = true;
00449 e = base.firstChild().toElement();
00450 for ( ; !e.isNull(); e = e.nextSibling().toElement() )
00451 {
00452 tag = e.tagName();
00453
00454 if ( tag == tagAction )
00455 {
00456
00457
00458
00459 if ( actionCollection->action( e.attribute( attrName ).utf8() ) )
00460 {
00461 deleteMe = false;
00462 break;
00463 }
00464 }
00465 else if ( tag == tagSeparator )
00466 {
00467
00468
00469
00470 QString weakAttr = e.attribute( attrWeakSeparator );
00471 if ( weakAttr.isEmpty() || weakAttr.toInt() != 1 )
00472 {
00473 deleteMe = false;
00474 break;
00475 }
00476 }
00477
00478
00479 else if ( tag == tagMerge )
00480 {
00481
00482
00483 continue;
00484 }
00485
00486
00487 else if ( tag == tagText )
00488 {
00489 continue;
00490 }
00491
00492
00493
00494
00495
00496 else
00497 {
00498 deleteMe = false;
00499 break;
00500 }
00501 }
00502
00503 return deleteMe;
00504 }
00505
00506 QDomElement KXMLGUIClient::findMatchingElement( const QDomElement &base, const QDomElement &additive )
00507 {
00508 static const QString &tagAction = KGlobal::staticQString( "Action" );
00509 static const QString &tagMergeLocal = KGlobal::staticQString( "MergeLocal" );
00510 static const QString &attrName = KGlobal::staticQString( "name" );
00511
00512 QDomElement e = additive.firstChild().toElement();
00513 for ( ; !e.isNull(); e = e.nextSibling().toElement() )
00514 {
00515
00516 if ( ( e.tagName() == tagAction ) || ( e.tagName() == tagMergeLocal ) )
00517 {
00518 continue;
00519 }
00520
00521
00522 if ( ( e.tagName() == base.tagName() ) &&
00523 ( e.attribute( attrName ) == base.attribute( attrName ) ) )
00524 {
00525 return e;
00526 }
00527 }
00528
00529
00530 return e;
00531 }
00532
00533 void KXMLGUIClient::conserveMemory()
00534 {
00535 d->m_doc = QDomDocument();
00536 d->m_buildDocument = QDomDocument();
00537 }
00538
00539 void KXMLGUIClient::setXMLGUIBuildDocument( const QDomDocument &doc )
00540 {
00541 d->m_buildDocument = doc;
00542 }
00543
00544 QDomDocument KXMLGUIClient::xmlguiBuildDocument() const
00545 {
00546 return d->m_buildDocument;
00547 }
00548
00549 void KXMLGUIClient::setFactory( KXMLGUIFactory *factory )
00550 {
00551 d->m_factory = factory;
00552 }
00553
00554 KXMLGUIFactory *KXMLGUIClient::factory() const
00555 {
00556 return d->m_factory;
00557 }
00558
00559 KXMLGUIClient *KXMLGUIClient::parentClient() const
00560 {
00561 return d->m_parent;
00562 }
00563
00564 void KXMLGUIClient::insertChildClient( KXMLGUIClient *child )
00565 {
00566 if ( child->d->m_parent )
00567 child->d->m_parent->removeChildClient( child );
00568 d->m_children.append( child );
00569 child->d->m_parent = this;
00570 }
00571
00572 void KXMLGUIClient::removeChildClient( KXMLGUIClient *child )
00573 {
00574 assert( d->m_children.containsRef( child ) );
00575 d->m_children.removeRef( child );
00576 child->d->m_parent = 0;
00577 }
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587 const QPtrList<KXMLGUIClient> *KXMLGUIClient::childClients()
00588 {
00589 return &d->m_children;
00590 }
00591
00592 void KXMLGUIClient::setClientBuilder( KXMLGUIBuilder *builder )
00593 {
00594 d->m_builder = builder;
00595 if ( builder )
00596 builder->setBuilderInstance( instance() );
00597 }
00598
00599 KXMLGUIBuilder *KXMLGUIClient::clientBuilder() const
00600 {
00601 return d->m_builder;
00602 }
00603
00604 void KXMLGUIClient::plugActionList( const QString &name, const QPtrList<KAction> &actionList )
00605 {
00606 if ( !d->m_factory )
00607 return;
00608
00609 d->m_factory->plugActionList( this, name, actionList );
00610 }
00611
00612 void KXMLGUIClient::unplugActionList( const QString &name )
00613 {
00614 if ( !d->m_factory )
00615 return;
00616
00617 d->m_factory->unplugActionList( this, name );
00618 }
00619
00620 QString KXMLGUIClient::findMostRecentXMLFile( const QStringList &files, QString &doc )
00621 {
00622
00623 QValueList<DocStruct> allDocuments;
00624
00625 QStringList::ConstIterator it = files.begin();
00626 QStringList::ConstIterator end = files.end();
00627 for (; it != end; ++it )
00628 {
00629
00630 QString data = KXMLGUIFactory::readConfigFile( *it );
00631 DocStruct d;
00632 d.file = *it;
00633 d.data = data;
00634 allDocuments.append( d );
00635 }
00636
00637 QValueList<DocStruct>::Iterator best = allDocuments.end();
00638 uint bestVersion = 0;
00639
00640 QValueList<DocStruct>::Iterator docIt = allDocuments.begin();
00641 QValueList<DocStruct>::Iterator docEnd = allDocuments.end();
00642 for (; docIt != docEnd; ++docIt )
00643 {
00644 QString versionStr = findVersionNumber( (*docIt).data );
00645 if ( versionStr.isEmpty() )
00646 continue;
00647
00648 bool ok = false;
00649 uint version = versionStr.toUInt( &ok );
00650 if ( !ok )
00651 continue;
00652
00653
00654 if ( version > bestVersion )
00655 {
00656 best = docIt;
00657
00658 bestVersion = version;
00659 }
00660 }
00661
00662 if ( best != docEnd )
00663 {
00664 if ( best != allDocuments.begin() )
00665 {
00666 QValueList<DocStruct>::Iterator local = allDocuments.begin();
00667
00668
00669 QDomDocument document;
00670 document.setContent( (*local).data );
00671
00672 ActionPropertiesMap properties = extractActionProperties( document );
00673
00674
00675
00676
00677 if ( !properties.isEmpty() )
00678 {
00679
00680
00681 document.setContent( (*best).data );
00682
00683 storeActionProperties( document, properties );
00684
00685 (*local).data = document.toString();
00686
00687 best = local;
00688
00689
00690 QFile f( (*local).file );
00691 if ( f.open( IO_WriteOnly ) )
00692 {
00693 QCString utf8data = (*local).data.utf8();
00694 f.writeBlock( utf8data.data(), utf8data.length() );
00695 f.close();
00696 }
00697 }
00698 else
00699 {
00700 QString f = (*local).file;
00701 QString backup = f + QString::fromLatin1( ".backup" );
00702 QDir dir;
00703 dir.rename( f, backup );
00704 }
00705 }
00706 doc = (*best).data;
00707 return (*best).file;
00708 }
00709 else if ( files.count() > 0 )
00710 {
00711
00712 doc = (*allDocuments.begin()).data;
00713 return (*allDocuments.begin()).file;
00714 }
00715
00716 return QString::null;
00717 }
00718
00719
00720
00721 QString KXMLGUIClient::findVersionNumber( const QString &xml )
00722 {
00723 enum { ST_START, ST_AFTER_OPEN, ST_AFTER_GUI,
00724 ST_EXPECT_VERSION, ST_VERSION_NUM} state = ST_START;
00725 for (unsigned int pos = 0; pos < xml.length(); pos++)
00726 {
00727 switch (state)
00728 {
00729 case ST_START:
00730 if (xml[pos] == '<')
00731 state = ST_AFTER_OPEN;
00732 break;
00733 case ST_AFTER_OPEN:
00734 {
00735
00736 int guipos = xml.find("gui", pos, false );
00737 if (guipos == -1)
00738 return QString::null;
00739
00740 pos = guipos + 2;
00741 state = ST_AFTER_GUI;
00742 break;
00743 }
00744 case ST_AFTER_GUI:
00745 state = ST_EXPECT_VERSION;
00746 break;
00747 case ST_EXPECT_VERSION:
00748 {
00749 int verpos = xml.find("version=\"", pos, false );
00750 if (verpos == -1)
00751 return QString::null;
00752
00753 pos = verpos + 8;
00754 state = ST_VERSION_NUM;
00755 break;
00756 }
00757 case ST_VERSION_NUM:
00758 {
00759 unsigned int endpos;
00760 for (endpos = pos; endpos < xml.length(); endpos++)
00761 {
00762 if (xml[endpos].unicode() >= '0' && xml[endpos].unicode() <= '9')
00763 continue;
00764 if (xml[endpos].unicode() == '"')
00765 break;
00766 else
00767 {
00768 endpos = xml.length();
00769 }
00770 }
00771
00772 if (endpos != pos && endpos < xml.length() )
00773 {
00774 QString matchCandidate = xml.mid(pos, endpos - pos);
00775 return matchCandidate;
00776 }
00777
00778 state = ST_EXPECT_VERSION;
00779 break;
00780 }
00781 }
00782 }
00783
00784 return QString::null;
00785 }
00786
00787 KXMLGUIClient::ActionPropertiesMap KXMLGUIClient::extractActionProperties( const QDomDocument &doc )
00788 {
00789 ActionPropertiesMap properties;
00790
00791 QDomElement actionPropElement = doc.documentElement().namedItem( "ActionProperties" ).toElement();
00792
00793 if ( actionPropElement.isNull() )
00794 return properties;
00795
00796 QDomNode n = actionPropElement.firstChild();
00797 for (; !n.isNull(); n = n.nextSibling() )
00798 {
00799 QDomElement e = n.toElement();
00800 if ( e.isNull() )
00801 continue;
00802
00803 if ( e.tagName().lower() != "action" )
00804 continue;
00805
00806 QString actionName = e.attribute( "name" );
00807
00808 if ( actionName.isEmpty() )
00809 continue;
00810
00811 QMap<QString, QMap<QString, QString> >::Iterator propIt = properties.find( actionName );
00812 if ( propIt == properties.end() )
00813 propIt = properties.insert( actionName, QMap<QString, QString>() );
00814
00815 QDomNamedNodeMap attributes = e.attributes();
00816 for ( uint i = 0; i < attributes.length(); ++i )
00817 {
00818 QDomAttr attr = attributes.item( i ).toAttr();
00819
00820 if ( attr.isNull() )
00821 continue;
00822
00823 QString name = attr.name();
00824
00825 if ( name == "name" || name.isEmpty() )
00826 continue;
00827
00828 (*propIt)[ name ] = attr.value();
00829 }
00830
00831 }
00832
00833 return properties;
00834 }
00835
00836 void KXMLGUIClient::storeActionProperties( QDomDocument &doc, const ActionPropertiesMap &properties )
00837 {
00838 QDomElement actionPropElement = doc.documentElement().namedItem( "ActionProperties" ).toElement();
00839
00840 if ( actionPropElement.isNull() )
00841 {
00842 actionPropElement = doc.createElement( "ActionProperties" );
00843 doc.documentElement().appendChild( actionPropElement );
00844 }
00845
00846 while ( !actionPropElement.firstChild().isNull() )
00847 actionPropElement.removeChild( actionPropElement.firstChild() );
00848
00849 ActionPropertiesMap::ConstIterator it = properties.begin();
00850 ActionPropertiesMap::ConstIterator end = properties.end();
00851 for (; it != end; ++it )
00852 {
00853 QDomElement action = doc.createElement( "Action" );
00854 action.setAttribute( "name", it.key() );
00855 actionPropElement.appendChild( action );
00856
00857 QMap<QString, QString> attributes = (*it);
00858 QMap<QString, QString>::ConstIterator attrIt = attributes.begin();
00859 QMap<QString, QString>::ConstIterator attrEnd = attributes.end();
00860 for (; attrIt != attrEnd; ++attrIt )
00861 action.setAttribute( attrIt.key(), attrIt.data() );
00862 }
00863 }
00864
00865 void KXMLGUIClient::addStateActionEnabled(const QString& state,
00866 const QString& action)
00867 {
00868 StateChange stateChange = getActionsToChangeForState(state);
00869
00870 stateChange.actionsToEnable.append( action );
00871
00872
00873 m_actionsStateMap.replace( state, stateChange );
00874 }
00875
00876
00877 void KXMLGUIClient::addStateActionDisabled(const QString& state,
00878 const QString& action)
00879 {
00880 StateChange stateChange = getActionsToChangeForState(state);
00881
00882 stateChange.actionsToDisable.append( action );
00883
00884
00885 m_actionsStateMap.replace( state, stateChange );
00886 }
00887
00888
00889 KXMLGUIClient::StateChange KXMLGUIClient::getActionsToChangeForState(const QString& state)
00890 {
00891 return m_actionsStateMap[state];
00892 }
00893
00894
00895 void KXMLGUIClient::stateChanged(const QString &newstate, KXMLGUIClient::ReverseStateChange reverse)
00896 {
00897 StateChange stateChange = getActionsToChangeForState(newstate);
00898
00899 bool setTrue = (reverse == StateNoReverse);
00900 bool setFalse = !setTrue;
00901
00902
00903
00904 for ( QStringList::Iterator it = stateChange.actionsToEnable.begin();
00905 it != stateChange.actionsToEnable.end(); ++it ) {
00906
00907 KAction *action = actionCollection()->action((*it).latin1());
00908 if (action) action->setEnabled(setTrue);
00909 }
00910
00911
00912
00913 for ( QStringList::Iterator it = stateChange.actionsToDisable.begin();
00914 it != stateChange.actionsToDisable.end(); ++it ) {
00915
00916 KAction *action = actionCollection()->action((*it).latin1());
00917 if (action) action->setEnabled(setFalse);
00918 }
00919
00920 }
00921
00922 void KXMLGUIClient::beginXMLPlug( QWidget *w )
00923 {
00924 actionCollection()->beginXMLPlug( w );
00925 QPtrListIterator<KXMLGUIClient> childIt( d->m_children );
00926 for (; childIt.current(); ++childIt )
00927 childIt.current()->actionCollection()->beginXMLPlug( w );
00928 }
00929
00930 void KXMLGUIClient::endXMLPlug()
00931 {
00932 actionCollection()->endXMLPlug();
00933 QPtrListIterator<KXMLGUIClient> childIt( d->m_children );
00934 for (; childIt.current(); ++childIt )
00935 childIt.current()->actionCollection()->endXMLPlug();
00936 }
00937
00938 void KXMLGUIClient::prepareXMLUnplug( QWidget * )
00939 {
00940 actionCollection()->prepareXMLUnplug();
00941 QPtrListIterator<KXMLGUIClient> childIt( d->m_children );
00942 for (; childIt.current(); ++childIt )
00943 childIt.current()->actionCollection()->prepareXMLUnplug();
00944 }
00945
00946 void KXMLGUIClient::virtual_hook( int, void* )
00947 { }