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