• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • tdeui
 

tdeui

  • tdeui
kxmlguiclient.cpp
1/* This file is part of the KDE libraries
2 Copyright (C) 2000 Simon Hausmann <hausmann@kde.org>
3 Copyright (C) 2000 Kurt Granroth <granroth@kde.org>
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License version 2 as published by the Free Software Foundation.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 Boston, MA 02110-1301, USA.
18*/
19
20#include "kxmlguiclient.h"
21#include "kxmlguifactory.h"
22#include "kxmlguibuilder.h"
23
24#include <tqdir.h>
25#include <tqfile.h>
26#include <tqdom.h>
27#include <tqtextstream.h>
28#include <tqregexp.h>
29#include <tqguardedptr.h>
30
31#include <kinstance.h>
32#include <tdestandarddirs.h>
33#include <kdebug.h>
34#include <tdeaction.h>
35#include <tdeapplication.h>
36
37#include <assert.h>
38
39class KXMLGUIClientPrivate
40{
41public:
42 KXMLGUIClientPrivate()
43 {
44 m_instance = TDEGlobal::instance();
45 m_parent = 0L;
46 m_builder = 0L;
47 m_actionCollection = 0;
48 }
49 ~KXMLGUIClientPrivate()
50 {
51 }
52
53 TDEInstance *m_instance;
54
55 TQDomDocument m_doc;
56 TDEActionCollection *m_actionCollection;
57 TQDomDocument m_buildDocument;
58 TQGuardedPtr<KXMLGUIFactory> m_factory;
59 KXMLGUIClient *m_parent;
60 //TQPtrList<KXMLGUIClient> m_supers;
61 TQPtrList<KXMLGUIClient> m_children;
62 KXMLGUIBuilder *m_builder;
63 TQString m_xmlFile;
64 TQString m_localXMLFile;
65};
66
67KXMLGUIClient::KXMLGUIClient()
68{
69 d = new KXMLGUIClientPrivate;
70}
71
72KXMLGUIClient::KXMLGUIClient( KXMLGUIClient *parent )
73{
74 d = new KXMLGUIClientPrivate;
75 parent->insertChildClient( this );
76}
77
78KXMLGUIClient::~KXMLGUIClient()
79{
80 if ( d->m_parent )
81 d->m_parent->removeChildClient( this );
82
83 TQPtrListIterator<KXMLGUIClient> it( d->m_children );
84 for ( ; it.current(); ++it ) {
85 assert( it.current()->d->m_parent == this );
86 it.current()->d->m_parent = 0;
87 }
88
89 delete d->m_actionCollection;
90 delete d;
91}
92
93TDEAction *KXMLGUIClient::action( const char *name ) const
94{
95 TDEAction* act = actionCollection()->action( name );
96 if ( !act ) {
97 TQPtrListIterator<KXMLGUIClient> childIt( d->m_children );
98 for (; childIt.current(); ++childIt ) {
99 act = childIt.current()->actionCollection()->action( name );
100 if ( act )
101 break;
102 }
103 }
104 return act;
105}
106
107TDEActionCollection *KXMLGUIClient::actionCollection() const
108{
109 if ( !d->m_actionCollection )
110 {
111 d->m_actionCollection = new TDEActionCollection(
112 "KXMLGUIClient-TDEActionCollection", this );
113 }
114 return d->m_actionCollection;
115}
116
117TDEAction *KXMLGUIClient::action( const TQDomElement &element ) const
118{
119 static const TQString &attrName = TDEGlobal::staticQString( "name" );
120 return actionCollection()->action( element.attribute( attrName ).latin1() );
121}
122
123TDEInstance *KXMLGUIClient::instance() const
124{
125 return d->m_instance;
126}
127
128TQDomDocument KXMLGUIClient::domDocument() const
129{
130 return d->m_doc;
131}
132
133TQString KXMLGUIClient::xmlFile() const
134{
135 return d->m_xmlFile;
136}
137
138TQString KXMLGUIClient::localXMLFile() const
139{
140 if ( !d->m_localXMLFile.isEmpty() )
141 return d->m_localXMLFile;
142
143 if ( !TQDir::isRelativePath(d->m_xmlFile) )
144 return TQString::null; // can't save anything here
145
146 return locateLocal( "data", TQString::fromLatin1( instance()->instanceName() + '/' ) + d->m_xmlFile );
147}
148
149
150void KXMLGUIClient::reloadXML()
151{
152 TQString file( xmlFile() );
153 if ( !file.isEmpty() )
154 setXMLFile( file );
155}
156
157void KXMLGUIClient::setInstance( TDEInstance *instance )
158{
159 d->m_instance = instance;
160 actionCollection()->setInstance( instance );
161 if ( d->m_builder )
162 d->m_builder->setBuilderClient( this );
163}
164
165void KXMLGUIClient::setXMLFile( const TQString& _file, bool merge, bool setXMLDoc )
166{
167 // store our xml file name
168 if ( !_file.isNull() ) {
169 d->m_xmlFile = _file;
170 actionCollection()->setXMLFile( _file );
171 }
172
173 if ( !setXMLDoc )
174 return;
175
176 TQString file = _file;
177 if ( TQDir::isRelativePath(file) )
178 {
179 TQString doc;
180
181 TQString filter = TQString::fromLatin1( instance()->instanceName() + '/' ) + _file;
182
183 TQStringList allFiles = instance()->dirs()->findAllResources( "data", filter ) + instance()->dirs()->findAllResources( "data", _file );
184
185 file = findMostRecentXMLFile( allFiles, doc );
186
187 if ( file.isEmpty() )
188 {
189 // this might or might not be an error. for the time being,
190 // let's treat this as if it isn't a problem and the user just
191 // wants the global standards file
192
193 // however if a non-empty file gets passed and we can't find it we might
194 // inform the developer using some debug output
195 if ( !_file.isEmpty() )
196 kdWarning() << "KXMLGUIClient::setXMLFile: cannot find .rc file " << _file << endl;
197
198 setXML( TQString::null, true );
199 return;
200 }
201 else if ( !doc.isEmpty() )
202 {
203 setXML( doc, merge );
204 return;
205 }
206 }
207
208 TQString xml = KXMLGUIFactory::readConfigFile( file );
209 setXML( xml, merge );
210}
211
212void KXMLGUIClient::setLocalXMLFile( const TQString &file )
213{
214 d->m_localXMLFile = file;
215}
216
217void KXMLGUIClient::setXML( const TQString &document, bool merge )
218{
219 TQDomDocument doc;
220 doc.setContent( document );
221 setDOMDocument( doc, merge );
222}
223
224void KXMLGUIClient::setDOMDocument( const TQDomDocument &document, bool merge )
225{
226 if ( merge )
227 {
228 TQDomElement base = d->m_doc.documentElement();
229
230 TQDomElement e = document.documentElement();
231
232 // merge our original (global) xml with our new one
233 mergeXML(base, e, actionCollection());
234
235 // reassign our pointer as mergeXML might have done something
236 // strange to it
237 base = d->m_doc.documentElement();
238
239 // we want some sort of failsafe.. just in case
240 if ( base.isNull() )
241 d->m_doc = document;
242 }
243 else
244 {
245 d->m_doc = document;
246 }
247
248 setXMLGUIBuildDocument( TQDomDocument() );
249}
250
251bool KXMLGUIClient::mergeXML( TQDomElement &base, const TQDomElement &additive, TDEActionCollection *actionCollection )
252{
253 static const TQString &tagAction = TDEGlobal::staticQString( "Action" );
254 static const TQString &tagMerge = TDEGlobal::staticQString( "Merge" );
255 static const TQString &tagSeparator = TDEGlobal::staticQString( "Separator" );
256 static const TQString &attrName = TDEGlobal::staticQString( "name" );
257 static const TQString &attrAppend = TDEGlobal::staticQString( "append" );
258 static const TQString &attrWeakSeparator = TDEGlobal::staticQString( "weakSeparator" );
259 static const TQString &tagMergeLocal = TDEGlobal::staticQString( "MergeLocal" );
260 static const TQString &tagText = TDEGlobal::staticQString( "text" );
261 static const TQString &attrAlreadyVisited = TDEGlobal::staticQString( "alreadyVisited" );
262 static const TQString &attrNoMerge = TDEGlobal::staticQString( "noMerge" );
263 static const TQString &attrOne = TDEGlobal::staticQString( "1" );
264
265 // there is a possibility that we don't want to merge in the
266 // additive.. rather, we might want to *replace* the base with the
267 // additive. this can be for any container.. either at a file wide
268 // level or a simple container level. we look for the 'noMerge'
269 // tag, in any event and just replace the old with the new
270 if ( additive.attribute(attrNoMerge) == attrOne ) // ### use toInt() instead? (Simon)
271 {
272 base.parentNode().replaceChild(additive, base);
273 return true;
274 }
275
276 TQString tag;
277
278 // iterate over all elements in the container (of the global DOM tree)
279 TQDomNode n = base.firstChild();
280 while ( !n.isNull() )
281 {
282 TQDomElement e = n.toElement();
283 n = n.nextSibling(); // Advance now so that we can safely delete e
284 if (e.isNull())
285 continue;
286
287 tag = e.tagName();
288
289 // if there's an action tag in the global tree and the action is
290 // not implemented, then we remove the element
291 if ( tag == tagAction )
292 {
293 TQCString name = e.attribute( attrName ).utf8(); // WABA
294 if ( !actionCollection->action( name.data() ) ||
295 (tdeApp && !tdeApp->authorizeTDEAction(name)))
296 {
297 // remove this child as we aren't using it
298 base.removeChild( e );
299 continue;
300 }
301 }
302
303 // if there's a separator defined in the global tree, then add an
304 // attribute, specifying that this is a "weak" separator
305 else if ( tag == tagSeparator )
306 {
307 e.setAttribute( attrWeakSeparator, (uint)1 );
308
309 // okay, hack time. if the last item was a weak separator OR
310 // this is the first item in a container, then we nuke the
311 // current one
312 TQDomElement prev = e.previousSibling().toElement();
313 if ( prev.isNull() ||
314 ( prev.tagName() == tagSeparator && !prev.attribute( attrWeakSeparator ).isNull() ) ||
315 ( prev.tagName() == tagText ) )
316 {
317 // the previous element was a weak separator or didn't exist
318 base.removeChild( e );
319 continue;
320 }
321 }
322
323 // the MergeLocal tag lets us specify where non-standard elements
324 // of the local tree shall be merged in. After inserting the
325 // elements we delete this element
326 else if ( tag == tagMergeLocal )
327 {
328 TQDomNode it = additive.firstChild();
329 while ( !it.isNull() )
330 {
331 TQDomElement newChild = it.toElement();
332 it = it.nextSibling();
333 if (newChild.isNull() )
334 continue;
335
336 if ( newChild.tagName() == tagText )
337 continue;
338
339 if ( newChild.attribute( attrAlreadyVisited ) == attrOne )
340 continue;
341
342 TQString itAppend( newChild.attribute( attrAppend ) );
343 TQString elemName( e.attribute( attrName ) );
344
345 if ( ( itAppend.isNull() && elemName.isEmpty() ) ||
346 ( itAppend == elemName ) )
347 {
348 // first, see if this new element matches a standard one in
349 // the global file. if it does, then we skip it as it will
350 // be merged in, later
351 TQDomElement matchingElement = findMatchingElement( newChild, base );
352 if ( matchingElement.isNull() || newChild.tagName() == tagSeparator )
353 base.insertBefore( newChild, e );
354 }
355 }
356
357 base.removeChild( e );
358 continue;
359 }
360
361 // in this last case we check for a separator tag and, if not, we
362 // can be sure that its a container --> proceed with child nodes
363 // recursively and delete the just proceeded container item in
364 // case its empty (if the recursive call returns true)
365 else if ( tag != tagMerge )
366 {
367 // handle the text tag
368 if ( tag == tagText )
369 continue;
370
371 TQDomElement matchingElement = findMatchingElement( e, additive );
372
373 if ( !matchingElement.isNull() )
374 {
375 matchingElement.setAttribute( attrAlreadyVisited, (uint)1 );
376
377 if ( mergeXML( e, matchingElement, actionCollection ) )
378 {
379 base.removeChild( e );
380 continue;
381 }
382
383 // Merge attributes
384 const TQDomNamedNodeMap attribs = matchingElement.attributes();
385 const uint attribcount = attribs.count();
386
387 for(uint i = 0; i < attribcount; ++i)
388 {
389 const TQDomNode node = attribs.item(i);
390 e.setAttribute(node.nodeName(), node.nodeValue());
391 }
392
393 continue;
394 }
395 else
396 {
397 // this is an important case here! We reach this point if the
398 // "local" tree does not contain a container definition for
399 // this container. However we have to call mergeXML recursively
400 // and make it check if there are actions implemented for this
401 // container. *If* none, then we can remove this container now
402 if ( mergeXML( e, TQDomElement(), actionCollection ) )
403 base.removeChild( e );
404 continue;
405 }
406 }
407 }
408
409 //here we append all child elements which were not inserted
410 //previously via the LocalMerge tag
411 n = additive.firstChild();
412 while ( !n.isNull() )
413 {
414 TQDomElement e = n.toElement();
415 n = n.nextSibling(); // Advance now so that we can safely delete e
416 if (e.isNull())
417 continue;
418
419 TQDomElement matchingElement = findMatchingElement( e, base );
420
421 if ( matchingElement.isNull() )
422 {
423 base.appendChild( e );
424 }
425 }
426
427 // do one quick check to make sure that the last element was not
428 // a weak separator
429 TQDomElement last = base.lastChild().toElement();
430 if ( (last.tagName() == tagSeparator) && (!last.attribute( attrWeakSeparator ).isNull()) )
431 {
432 base.removeChild( last );
433 }
434
435 // now we check if we are empty (in which case we return "true", to
436 // indicate the caller that it can delete "us" (the base element
437 // argument of "this" call)
438 bool deleteMe = true;
439
440 n = base.firstChild();
441 while ( !n.isNull() )
442 {
443 TQDomElement e = n.toElement();
444 n = n.nextSibling(); // Advance now so that we can safely delete e
445 if (e.isNull())
446 continue;
447
448 tag = e.tagName();
449
450 if ( tag == tagAction )
451 {
452 // if base contains an implemented action, then we must not get
453 // deleted (note that the actionCollection contains both,
454 // "global" and "local" actions
455 if ( actionCollection->action( e.attribute( attrName ).utf8().data() ) )
456 {
457 deleteMe = false;
458 break;
459 }
460 }
461 else if ( tag == tagSeparator )
462 {
463 // if we have a separator which has *not* the weak attribute
464 // set, then it must be owned by the "local" tree in which case
465 // we must not get deleted either
466 TQString weakAttr = e.attribute( attrWeakSeparator );
467 if ( weakAttr.isEmpty() || weakAttr.toInt() != 1 )
468 {
469 deleteMe = false;
470 break;
471 }
472 }
473
474 // in case of a merge tag we have unlimited lives, too ;-)
475 else if ( tag == tagMerge )
476 {
477// deleteMe = false;
478// break;
479 continue;
480 }
481
482 // a text tag is NOT enough to spare this container
483 else if ( tag == tagText )
484 {
485 continue;
486 }
487
488 // what's left are non-empty containers! *don't* delete us in this
489 // case (at this position we can be *sure* that the container is
490 // *not* empty, as the recursive call for it was in the first loop
491 // which deleted the element in case the call returned "true"
492 else
493 {
494 deleteMe = false;
495 break;
496 }
497 }
498
499 return deleteMe;
500}
501
502TQDomElement KXMLGUIClient::findMatchingElement( const TQDomElement &base, const TQDomElement &additive )
503{
504 static const TQString &tagAction = TDEGlobal::staticQString( "Action" );
505 static const TQString &tagMergeLocal = TDEGlobal::staticQString( "MergeLocal" );
506 static const TQString &attrName = TDEGlobal::staticQString( "name" );
507
508 TQDomNode n = additive.firstChild();
509 while ( !n.isNull() )
510 {
511 TQDomElement e = n.toElement();
512 n = n.nextSibling(); // Advance now so that we can safely delete e
513 if (e.isNull())
514 continue;
515
516 // skip all action and merge tags as we will never use them
517 if ( ( e.tagName() == tagAction ) || ( e.tagName() == tagMergeLocal ) )
518 {
519 continue;
520 }
521
522 // now see if our tags are equivalent
523 if ( ( e.tagName() == base.tagName() ) &&
524 ( e.attribute( attrName ) == base.attribute( attrName ) ) )
525 {
526 return e;
527 }
528 }
529
530 // nope, return a (now) null element
531 return TQDomElement();
532}
533
534void KXMLGUIClient::conserveMemory()
535{
536 d->m_doc = TQDomDocument();
537 d->m_buildDocument = TQDomDocument();
538}
539
540void KXMLGUIClient::setXMLGUIBuildDocument( const TQDomDocument &doc )
541{
542 d->m_buildDocument = doc;
543}
544
545TQDomDocument KXMLGUIClient::xmlguiBuildDocument() const
546{
547 return d->m_buildDocument;
548}
549
550void KXMLGUIClient::setFactory( KXMLGUIFactory *factory )
551{
552 d->m_factory = factory;
553}
554
555KXMLGUIFactory *KXMLGUIClient::factory() const
556{
557 return d->m_factory;
558}
559
560KXMLGUIClient *KXMLGUIClient::parentClient() const
561{
562 return d->m_parent;
563}
564
565void KXMLGUIClient::insertChildClient( KXMLGUIClient *child )
566{
567 if ( child->d->m_parent )
568 child->d->m_parent->removeChildClient( child );
569 d->m_children.append( child );
570 child->d->m_parent = this;
571}
572
573void KXMLGUIClient::removeChildClient( KXMLGUIClient *child )
574{
575 assert( d->m_children.containsRef( child ) );
576 d->m_children.removeRef( child );
577 child->d->m_parent = 0;
578}
579
580/*bool KXMLGUIClient::addSuperClient( KXMLGUIClient *super )
581{
582 if ( d->m_supers.contains( super ) )
583 return false;
584 d->m_supers.append( super );
585 return true;
586}*/
587
588const TQPtrList<KXMLGUIClient> *KXMLGUIClient::childClients()
589{
590 return &d->m_children;
591}
592
593void KXMLGUIClient::setClientBuilder( KXMLGUIBuilder *builder )
594{
595 d->m_builder = builder;
596 if ( builder )
597 builder->setBuilderInstance( instance() );
598}
599
600KXMLGUIBuilder *KXMLGUIClient::clientBuilder() const
601{
602 return d->m_builder;
603}
604
605void KXMLGUIClient::plugActionList( const TQString &name, const TQPtrList<TDEAction> &actionList )
606{
607 if ( !d->m_factory )
608 return;
609
610 d->m_factory->plugActionList( this, name, actionList );
611}
612
613void KXMLGUIClient::unplugActionList( const TQString &name )
614{
615 if ( !d->m_factory )
616 return;
617
618 d->m_factory->unplugActionList( this, name );
619}
620
621TQString KXMLGUIClient::findMostRecentXMLFile( const TQStringList &files, TQString &doc )
622{
623
624 TQValueList<DocStruct> allDocuments;
625
626 TQStringList::ConstIterator it = files.begin();
627 TQStringList::ConstIterator end = files.end();
628 for (; it != end; ++it )
629 {
630 //kdDebug() << "KXMLGUIClient::findMostRecentXMLFile " << *it << endl;
631 TQString data = KXMLGUIFactory::readConfigFile( *it );
632 DocStruct d;
633 d.file = *it;
634 d.data = data;
635 allDocuments.append( d );
636 }
637
638 TQValueList<DocStruct>::Iterator best = allDocuments.end();
639 uint bestVersion = 0;
640
641 TQValueList<DocStruct>::Iterator docIt = allDocuments.begin();
642 TQValueList<DocStruct>::Iterator docEnd = allDocuments.end();
643 for (; docIt != docEnd; ++docIt )
644 {
645 TQString versionStr = findVersionNumber( (*docIt).data );
646 if ( versionStr.isEmpty() )
647 continue;
648
649 bool ok = false;
650 uint version = versionStr.toUInt( &ok );
651 if ( !ok )
652 continue;
653 //kdDebug() << "FOUND VERSION " << version << endl;
654
655 if ( version > bestVersion )
656 {
657 best = docIt;
658 //kdDebug() << "best version is now " << version << endl;
659 bestVersion = version;
660 }
661 }
662
663 if ( best != docEnd )
664 {
665 if ( best != allDocuments.begin() )
666 {
667 TQValueList<DocStruct>::Iterator local = allDocuments.begin();
668
669 // load the local document and extract the action properties
670 TQDomDocument document;
671 document.setContent( (*local).data );
672
673 ActionPropertiesMap properties = extractActionProperties( document );
674
675 // in case the document has a ActionProperties section
676 // we must not delete it but copy over the global doc
677 // to the local and insert the ActionProperties section
678 if ( !properties.isEmpty() )
679 {
680 // now load the global one with the higher version number
681 // into memory
682 document.setContent( (*best).data );
683 // and store the properties in there
684 storeActionProperties( document, properties );
685
686 (*local).data = document.toString();
687 // make sure we pick up the new local doc, when we return later
688 best = local;
689
690 // write out the new version of the local document
691 TQFile f( (*local).file );
692 if ( f.open( IO_WriteOnly ) )
693 {
694 TQCString utf8data = (*local).data.utf8();
695 f.writeBlock( utf8data.data(), utf8data.length() );
696 f.close();
697 }
698 }
699 else
700 {
701 TQString f = (*local).file;
702 TQString backup = f + TQString::fromLatin1( ".backup" );
703 TQDir dir;
704 dir.rename( f, backup );
705 }
706 }
707 doc = (*best).data;
708 return (*best).file;
709 }
710 else if ( files.count() > 0 )
711 {
712 //kdDebug() << "returning first one..." << endl;
713 doc = (*allDocuments.begin()).data;
714 return (*allDocuments.begin()).file;
715 }
716
717 return TQString::null;
718}
719
720
721
722TQString KXMLGUIClient::findVersionNumber( const TQString &xml )
723{
724 enum { ST_START, ST_AFTER_OPEN, ST_AFTER_GUI,
725 ST_EXPECT_VERSION, ST_VERSION_NUM} state = ST_START;
726 for (unsigned int pos = 0; pos < xml.length(); pos++)
727 {
728 switch (state)
729 {
730 case ST_START:
731 if (xml[pos] == '<')
732 state = ST_AFTER_OPEN;
733 break;
734 case ST_AFTER_OPEN:
735 {
736 //Jump to gui..
737 int guipos = xml.find("gui", pos, false /*case-insensitive*/);
738 if (guipos == -1)
739 return TQString::null; //Reject
740
741 pos = guipos + 2; //Position at i, so we're moved ahead to the next character by the ++;
742 state = ST_AFTER_GUI;
743 break;
744 }
745 case ST_AFTER_GUI:
746 state = ST_EXPECT_VERSION;
747 break;
748 case ST_EXPECT_VERSION:
749 {
750 int verpos = xml.find("version=\"", pos, false /*case-insensitive*/);
751 if (verpos == -1)
752 return TQString::null; //Reject
753
754 pos = verpos + 8; //v = 0, e = +1, r = +2, s = +3 , i = +4, o = +5, n = +6, = = +7, " = + 8
755 state = ST_VERSION_NUM;
756 break;
757 }
758 case ST_VERSION_NUM:
759 {
760 unsigned int endpos;
761 for (endpos = pos; endpos < xml.length(); endpos++)
762 {
763 if (xml[endpos].unicode() >= '0' && xml[endpos].unicode() <= '9')
764 continue; //Number..
765 if (xml[endpos].unicode() == '"') //End of parameter
766 break;
767 else //This shouldn't be here..
768 {
769 endpos = xml.length();
770 }
771 }
772
773 if (endpos != pos && endpos < xml.length() )
774 {
775 TQString matchCandidate = xml.mid(pos, endpos - pos); //Don't include " ".
776 return matchCandidate;
777 }
778
779 state = ST_EXPECT_VERSION; //Try to match a well-formed version..
780 break;
781 } //case..
782 } //switch
783 } //for
784
785 return TQString::null;
786}
787
788KXMLGUIClient::ActionPropertiesMap KXMLGUIClient::extractActionProperties( const TQDomDocument &doc )
789{
790 ActionPropertiesMap properties;
791
792 TQDomElement actionPropElement = doc.documentElement().namedItem( "ActionProperties" ).toElement();
793
794 if ( actionPropElement.isNull() )
795 return properties;
796
797 TQDomNode n = actionPropElement.firstChild();
798 while(!n.isNull())
799 {
800 TQDomElement e = n.toElement();
801 n = n.nextSibling(); // Advance now so that we can safely delete e
802 if ( e.isNull() )
803 continue;
804
805 if ( e.tagName().lower() != "action" )
806 continue;
807
808 TQString actionName = e.attribute( "name" );
809
810 if ( actionName.isEmpty() )
811 continue;
812
813 TQMap<TQString, TQMap<TQString, TQString> >::Iterator propIt = properties.find( actionName );
814 if ( propIt == properties.end() )
815 propIt = properties.insert( actionName, TQMap<TQString, TQString>() );
816
817 const TQDomNamedNodeMap attributes = e.attributes();
818 const uint attributeslength = attributes.length();
819
820 for ( uint i = 0; i < attributeslength; ++i )
821 {
822 const TQDomAttr attr = attributes.item( i ).toAttr();
823
824 if ( attr.isNull() )
825 continue;
826
827 const TQString name = attr.name();
828
829 if ( name == "name" || name.isEmpty() )
830 continue;
831
832 (*propIt)[ name ] = attr.value();
833 }
834
835 }
836
837 return properties;
838}
839
840void KXMLGUIClient::storeActionProperties( TQDomDocument &doc, const ActionPropertiesMap &properties )
841{
842 TQDomElement actionPropElement = doc.documentElement().namedItem( "ActionProperties" ).toElement();
843
844 if ( actionPropElement.isNull() )
845 {
846 actionPropElement = doc.createElement( "ActionProperties" );
847 doc.documentElement().appendChild( actionPropElement );
848 }
849
850 while ( !actionPropElement.firstChild().isNull() )
851 actionPropElement.removeChild( actionPropElement.firstChild() );
852
853 ActionPropertiesMap::ConstIterator it = properties.begin();
854 ActionPropertiesMap::ConstIterator end = properties.end();
855 for (; it != end; ++it )
856 {
857 TQDomElement action = doc.createElement( "Action" );
858 action.setAttribute( "name", it.key() );
859 actionPropElement.appendChild( action );
860
861 TQMap<TQString, TQString> attributes = (*it);
862 TQMap<TQString, TQString>::ConstIterator attrIt = attributes.begin();
863 TQMap<TQString, TQString>::ConstIterator attrEnd = attributes.end();
864 for (; attrIt != attrEnd; ++attrIt )
865 action.setAttribute( attrIt.key(), attrIt.data() );
866 }
867}
868
869void KXMLGUIClient::addStateActionEnabled(const TQString& state,
870 const TQString& action)
871{
872 StateChange stateChange = getActionsToChangeForState(state);
873
874 stateChange.actionsToEnable.append( action );
875 //kdDebug() << "KXMLGUIClient::addStateActionEnabled( " << state << ", " << action << ")" << endl;
876
877 m_actionsStateMap.replace( state, stateChange );
878}
879
880
881void KXMLGUIClient::addStateActionDisabled(const TQString& state,
882 const TQString& action)
883{
884 StateChange stateChange = getActionsToChangeForState(state);
885
886 stateChange.actionsToDisable.append( action );
887 //kdDebug() << "KXMLGUIClient::addStateActionDisabled( " << state << ", " << action << ")" << endl;
888
889 m_actionsStateMap.replace( state, stateChange );
890}
891
892
893KXMLGUIClient::StateChange KXMLGUIClient::getActionsToChangeForState(const TQString& state)
894{
895 return m_actionsStateMap[state];
896}
897
898
899void KXMLGUIClient::stateChanged(const TQString &newstate, KXMLGUIClient::ReverseStateChange reverse)
900{
901 StateChange stateChange = getActionsToChangeForState(newstate);
902
903 bool setTrue = (reverse == StateNoReverse);
904 bool setFalse = !setTrue;
905
906 // Enable actions which need to be enabled...
907 //
908 for ( TQStringList::Iterator it = stateChange.actionsToEnable.begin();
909 it != stateChange.actionsToEnable.end(); ++it ) {
910
911 TDEAction *action = actionCollection()->action((*it).latin1());
912 if (action) action->setEnabled(setTrue);
913 }
914
915 // and disable actions which need to be disabled...
916 //
917 for ( TQStringList::Iterator it = stateChange.actionsToDisable.begin();
918 it != stateChange.actionsToDisable.end(); ++it ) {
919
920 TDEAction *action = actionCollection()->action((*it).latin1());
921 if (action) action->setEnabled(setFalse);
922 }
923
924}
925
926void KXMLGUIClient::beginXMLPlug( TQWidget *w )
927{
928 actionCollection()->beginXMLPlug( w );
929 TQPtrListIterator<KXMLGUIClient> childIt( d->m_children );
930 for (; childIt.current(); ++childIt )
931 childIt.current()->actionCollection()->beginXMLPlug( w );
932}
933
934void KXMLGUIClient::endXMLPlug()
935{
936 actionCollection()->endXMLPlug();
937 TQPtrListIterator<KXMLGUIClient> childIt( d->m_children );
938 for (; childIt.current(); ++childIt )
939 childIt.current()->actionCollection()->endXMLPlug();
940}
941
942void KXMLGUIClient::prepareXMLUnplug( TQWidget * )
943{
944 actionCollection()->prepareXMLUnplug();
945 TQPtrListIterator<KXMLGUIClient> childIt( d->m_children );
946 for (; childIt.current(); ++childIt )
947 childIt.current()->actionCollection()->prepareXMLUnplug();
948}
949
950void KXMLGUIClient::virtual_hook( int, void* )
951{ /*BASE::virtual_hook( id, data );*/ }
KXMLGUIBuilder
Abstract interface for a "GUI builder", used by the GUIFactory This interface is implemented by TDEMa...
Definition: kxmlguibuilder.h:40
KXMLGUIClient
A KXMLGUIClient can be used with KXMLGUIFactory to create a GUI from actions and an XML document,...
Definition: kxmlguiclient.h:44
KXMLGUIClient::parentClient
KXMLGUIClient * parentClient() const
KXMLGUIClients can form a simple child/parent object tree.
Definition: kxmlguiclient.cpp:560
KXMLGUIClient::plugActionList
void plugActionList(const TQString &name, const TQPtrList< TDEAction > &actionList)
ActionLists are a way for XMLGUI to support dynamic lists of actions.
Definition: kxmlguiclient.cpp:605
KXMLGUIClient::xmlFile
virtual TQString xmlFile() const
This will return the name of the XML file as set by setXMLFile().
Definition: kxmlguiclient.cpp:133
KXMLGUIClient::unplugActionList
void unplugActionList(const TQString &name)
The complement of plugActionList() ...
Definition: kxmlguiclient.cpp:613
KXMLGUIClient::KXMLGUIClient
KXMLGUIClient()
Constructs a KXMLGUIClient which can be used with a KXMLGUIFactory to create a GUI from actions and a...
Definition: kxmlguiclient.cpp:67
KXMLGUIClient::removeChildClient
void removeChildClient(KXMLGUIClient *child)
Removes the given child from the client's children list.
Definition: kxmlguiclient.cpp:573
KXMLGUIClient::instance
virtual TDEInstance * instance() const
Definition: kxmlguiclient.cpp:123
KXMLGUIClient::xmlguiBuildDocument
TQDomDocument xmlguiBuildDocument() const
Definition: kxmlguiclient.cpp:545
KXMLGUIClient::reloadXML
void reloadXML()
Forces this client to re-read its XML resource file.
Definition: kxmlguiclient.cpp:150
KXMLGUIClient::setXMLGUIBuildDocument
void setXMLGUIBuildDocument(const TQDomDocument &doc)
Definition: kxmlguiclient.cpp:540
KXMLGUIClient::setXMLFile
virtual void setXMLFile(const TQString &file, bool merge=false, bool setXMLDoc=true)
Sets the name of the rc file containing the XML for the part.
Definition: kxmlguiclient.cpp:165
KXMLGUIClient::endXMLPlug
void endXMLPlug()
Definition: kxmlguiclient.cpp:934
KXMLGUIClient::factory
KXMLGUIFactory * factory() const
Retrieves a pointer to the KXMLGUIFactory this client is associated with (will return 0L if the clien...
Definition: kxmlguiclient.cpp:555
KXMLGUIClient::setDOMDocument
virtual void setDOMDocument(const TQDomDocument &document, bool merge=false)
Sets the Document for the part, describing the layout of the GUI.
Definition: kxmlguiclient.cpp:224
KXMLGUIClient::prepareXMLUnplug
void prepareXMLUnplug(TQWidget *)
Definition: kxmlguiclient.cpp:942
KXMLGUIClient::~KXMLGUIClient
virtual ~KXMLGUIClient()
Destructs the KXMLGUIClient.
Definition: kxmlguiclient.cpp:78
KXMLGUIClient::setClientBuilder
void setClientBuilder(KXMLGUIBuilder *builder)
A client can have an own KXMLGUIBuilder.
Definition: kxmlguiclient.cpp:593
KXMLGUIClient::beginXMLPlug
void beginXMLPlug(TQWidget *)
Definition: kxmlguiclient.cpp:926
KXMLGUIClient::action
TDEAction * action(const char *name) const
Retrieves an action of the client by name.
Definition: kxmlguiclient.cpp:93
KXMLGUIClient::setXML
virtual void setXML(const TQString &document, bool merge=false)
Sets the XML for the part.
Definition: kxmlguiclient.cpp:217
KXMLGUIClient::conserveMemory
virtual void conserveMemory()
This function will attempt to give up some memory after the GUI is built.
Definition: kxmlguiclient.cpp:534
KXMLGUIClient::stateChanged
virtual void stateChanged(const TQString &newstate, ReverseStateChange reverse=StateNoReverse)
Actions can collectively be assigned a "State".
Definition: kxmlguiclient.cpp:899
KXMLGUIClient::setFactory
void setFactory(KXMLGUIFactory *factory)
This method is called by the KXMLGUIFactory as soon as the client is added to the KXMLGUIFactory's GU...
Definition: kxmlguiclient.cpp:550
KXMLGUIClient::clientBuilder
KXMLGUIBuilder * clientBuilder() const
Retrieves the client's GUI builder or 0L if no client specific builder has been assigned via setClien...
Definition: kxmlguiclient.cpp:600
KXMLGUIClient::childClients
const TQPtrList< KXMLGUIClient > * childClients()
Retrieves a list of all child clients.
Definition: kxmlguiclient.cpp:588
KXMLGUIClient::actionCollection
virtual TDEActionCollection * actionCollection() const
Retrieves the entire action collection for the GUI client.
Definition: kxmlguiclient.cpp:107
KXMLGUIClient::insertChildClient
void insertChildClient(KXMLGUIClient *child)
Use this method to make a client a child client of another client.
Definition: kxmlguiclient.cpp:565
KXMLGUIClient::setInstance
virtual void setInstance(TDEInstance *instance)
Returns true if client was added to super client list.
Definition: kxmlguiclient.cpp:157
KXMLGUIClient::domDocument
virtual TQDomDocument domDocument() const
Definition: kxmlguiclient.cpp:128
KXMLGUIFactory
KXMLGUIFactory, together with KXMLGUIClient objects, can be used to create a GUI of container widgets...
Definition: kxmlguifactory.h:62
TDEActionCollection
A managed set of TDEAction objects.
Definition: tdeactioncollection.h:79
TDEActionCollection::action
virtual TDEAction * action(int index) const
Return the TDEAction* at position "index" in the action collection.
Definition: tdeactioncollection.cpp:400
TDEActionCollection::setXMLFile
void setXMLFile(const TQString &)
Definition: tdeactioncollection.cpp:473
TDEAction
Class to encapsulate user-driven action or event.
Definition: tdeaction.h:203
TDEAction::setEnabled
virtual void setEnabled(bool enable)
Enables or disables this action.
Definition: tdeaction.cpp:832
TDEGlobal::instance
static TDEInstance * instance()
TDEGlobal::staticQString
static const TQString & staticQString(const char *str)
TDEInstance
TDEInstance::dirs
TDEStandardDirs * dirs() const
TDEStandardDirs::findAllResources
TQStringList findAllResources(const char *type, const TQString &filter=TQString::null, bool recursive=false, bool unique=false) const
kdWarning
kdbgstream kdWarning(int area=0)
endl
kndbgstream & endl(kndbgstream &s)
locateLocal
TQString locateLocal(const char *type, const TQString &filename, const TDEInstance *instance=TDEGlobal::instance())
KDE::version
unsigned int version()
TDEStdAccel::name
TQString name(StdAccel id)
TDEStdAccel::end
const TDEShortcut & end()

tdeui

Skip menu "tdeui"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

tdeui

Skip menu "tdeui"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdeioslave
  •   http
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdeui by doxygen 1.9.4
This website is maintained by Timothy Pearson.