• 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 <kstandarddirs.h>
33 #include <kdebug.h>
34 #include <tdeaction.h>
35 #include <tdeapplication.h>
36 
37 #include <assert.h>
38 
39 class KXMLGUIClientPrivate
40 {
41 public:
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 
67 KXMLGUIClient::KXMLGUIClient()
68 {
69  d = new KXMLGUIClientPrivate;
70 }
71 
72 KXMLGUIClient::KXMLGUIClient( KXMLGUIClient *parent )
73 {
74  d = new KXMLGUIClientPrivate;
75  parent->insertChildClient( this );
76 }
77 
78 KXMLGUIClient::~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 
93 TDEAction *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 
107 TDEActionCollection *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 
117 TDEAction *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 
123 TDEInstance *KXMLGUIClient::instance() const
124 {
125  return d->m_instance;
126 }
127 
128 TQDomDocument KXMLGUIClient::domDocument() const
129 {
130  return d->m_doc;
131 }
132 
133 TQString KXMLGUIClient::xmlFile() const
134 {
135  return d->m_xmlFile;
136 }
137 
138 TQString 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 
150 void KXMLGUIClient::reloadXML()
151 {
152  TQString file( xmlFile() );
153  if ( !file.isEmpty() )
154  setXMLFile( file );
155 }
156 
157 void 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 
165 void 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 
212 void KXMLGUIClient::setLocalXMLFile( const TQString &file )
213 {
214  d->m_localXMLFile = file;
215 }
216 
217 void KXMLGUIClient::setXML( const TQString &document, bool merge )
218 {
219  TQDomDocument doc;
220  doc.setContent( document );
221  setDOMDocument( doc, merge );
222 }
223 
224 void 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 
251 bool 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  (kapp && !kapp->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 
502 TQDomElement 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 
534 void KXMLGUIClient::conserveMemory()
535 {
536  d->m_doc = TQDomDocument();
537  d->m_buildDocument = TQDomDocument();
538 }
539 
540 void KXMLGUIClient::setXMLGUIBuildDocument( const TQDomDocument &doc )
541 {
542  d->m_buildDocument = doc;
543 }
544 
545 TQDomDocument KXMLGUIClient::xmlguiBuildDocument() const
546 {
547  return d->m_buildDocument;
548 }
549 
550 void KXMLGUIClient::setFactory( KXMLGUIFactory *factory )
551 {
552  d->m_factory = factory;
553 }
554 
555 KXMLGUIFactory *KXMLGUIClient::factory() const
556 {
557  return d->m_factory;
558 }
559 
560 KXMLGUIClient *KXMLGUIClient::parentClient() const
561 {
562  return d->m_parent;
563 }
564 
565 void 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 
573 void 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 
588 const TQPtrList<KXMLGUIClient> *KXMLGUIClient::childClients()
589 {
590  return &d->m_children;
591 }
592 
593 void KXMLGUIClient::setClientBuilder( KXMLGUIBuilder *builder )
594 {
595  d->m_builder = builder;
596  if ( builder )
597  builder->setBuilderInstance( instance() );
598 }
599 
600 KXMLGUIBuilder *KXMLGUIClient::clientBuilder() const
601 {
602  return d->m_builder;
603 }
604 
605 void 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 
613 void KXMLGUIClient::unplugActionList( const TQString &name )
614 {
615  if ( !d->m_factory )
616  return;
617 
618  d->m_factory->unplugActionList( this, name );
619 }
620 
621 TQString 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 
722 TQString 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 
788 KXMLGUIClient::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 
840 void 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 
869 void 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 
881 void 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 
893 KXMLGUIClient::StateChange KXMLGUIClient::getActionsToChangeForState(const TQString& state)
894 {
895  return m_actionsStateMap[state];
896 }
897 
898 
899 void 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 
926 void 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 
934 void 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 
942 void 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 
950 void KXMLGUIClient::virtual_hook( int, void* )
951 { /*BASE::virtual_hook( id, data );*/ }
KXMLGUIClient::conserveMemory
virtual void conserveMemory()
This function will attempt to give up some memory after the GUI is built.
Definition: kxmlguiclient.cpp:534
KXMLGUIClient::xmlguiBuildDocument
TQDomDocument xmlguiBuildDocument() const
Definition: kxmlguiclient.cpp:545
KXMLGUIClient::setXML
virtual void setXML(const TQString &document, bool merge=false)
Sets the XML for the part.
Definition: kxmlguiclient.cpp:217
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::prepareXMLUnplug
void prepareXMLUnplug(TQWidget *)
Definition: kxmlguiclient.cpp:942
KXMLGUIClient
A KXMLGUIClient can be used with KXMLGUIFactory to create a GUI from actions and an XML document...
Definition: kxmlguiclient.h:43
locateLocal
TQString locateLocal(const char *type, const TQString &filename, const TDEInstance *instance=TDEGlobal::instance())
KXMLGUIClient::setXMLGUIBuildDocument
void setXMLGUIBuildDocument(const TQDomDocument &doc)
Definition: kxmlguiclient.cpp:540
KXMLGUIClient::removeChildClient
void removeChildClient(KXMLGUIClient *child)
Removes the given child from the client's children list.
Definition: kxmlguiclient.cpp:573
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::setClientBuilder
void setClientBuilder(KXMLGUIBuilder *builder)
A client can have an own KXMLGUIBuilder.
Definition: kxmlguiclient.cpp:593
KXMLGUIClient::childClients
const TQPtrList< KXMLGUIClient > * childClients()
Retrieves a list of all child clients.
Definition: kxmlguiclient.cpp:588
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
TDEActionCollection::action
virtual TDEAction * action(int index) const
Return the TDEAction* at position "index" in the action collection.
Definition: tdeactioncollection.cpp:400
KXMLGUIClient::reloadXML
void reloadXML()
Forces this client to re-read its XML resource file.
Definition: kxmlguiclient.cpp:150
KXMLGUIClient::setInstance
virtual void setInstance(TDEInstance *instance)
Returns true if client was added to super client list.
Definition: kxmlguiclient.cpp:157
TDEActionCollection
A managed set of TDEAction objects.
Definition: tdeactioncollection.h:78
TDEAction
Class to encapsulate user-driven action or event.
Definition: tdeaction.h:202
KXMLGUIClient::stateChanged
virtual void stateChanged(const TQString &newstate, ReverseStateChange reverse=StateNoReverse)
Actions can collectively be assigned a "State".
Definition: kxmlguiclient.cpp:899
KXMLGUIClient::action
TDEAction * action(const char *name) const
Retrieves an action of the client by name.
Definition: kxmlguiclient.cpp:93
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::unplugActionList
void unplugActionList(const TQString &name)
The complement of plugActionList() ...
Definition: kxmlguiclient.cpp:613
KXMLGUIBuilder
Abstract interface for a "GUI builder", used by the GUIFactory This interface is implemented by TDEMa...
Definition: kxmlguibuilder.h:39
KXMLGUIClient::actionCollection
virtual TDEActionCollection * actionCollection() const
Retrieves the entire action collection for the GUI client.
Definition: kxmlguiclient.cpp:107
KXMLGUIClient::endXMLPlug
void endXMLPlug()
Definition: kxmlguiclient.cpp:934
TDEGlobal::instance
static TDEInstance * instance()
kdWarning
kdbgstream kdWarning(int area=0)
TDEActionCollection::setXMLFile
void setXMLFile(const TQString &)
Definition: tdeactioncollection.cpp:473
TDEGlobal::staticQString
static const TQString & staticQString(const char *str)
KXMLGUIFactory
KXMLGUIFactory, together with KXMLGUIClient objects, can be used to create a GUI of container widgets...
Definition: kxmlguifactory.h:61
TDEAction::setEnabled
virtual void setEnabled(bool enable)
Enables or disables this action.
Definition: tdeaction.cpp:832
KXMLGUIClient::parentClient
KXMLGUIClient * parentClient() const
KXMLGUIClients can form a simple child/parent object tree.
Definition: kxmlguiclient.cpp:560
KXMLGUIClient::domDocument
virtual TQDomDocument domDocument() const
Definition: kxmlguiclient.cpp:128
KDE::version
unsigned int version()
KXMLGUIClient::instance
virtual TDEInstance * instance() const
Definition: kxmlguiclient.cpp:123
KXMLGUIClient::beginXMLPlug
void beginXMLPlug(TQWidget *)
Definition: kxmlguiclient.cpp:926
KXMLGUIClient::~KXMLGUIClient
virtual ~KXMLGUIClient()
Destructs the KXMLGUIClient.
Definition: kxmlguiclient.cpp:78
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::insertChildClient
void insertChildClient(KXMLGUIClient *child)
Use this method to make a client a child client of another client.
Definition: kxmlguiclient.cpp:565
endl
kndbgstream & endl(kndbgstream &s)
TDEStdAccel::name
TQString name(StdAccel id)
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
TDEInstance
KXMLGUIClient::xmlFile
virtual TQString xmlFile() const
This will return the name of the XML file as set by setXMLFile().
Definition: kxmlguiclient.cpp:133
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

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
  •     tdecore
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  • tdeioslave
  •   http
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdeui by doxygen 1.8.8
This website is maintained by Timothy Pearson.