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
"KXMLGUIClient-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 { }