21 #include "kxmlguifactory.h" 22 #include "kxmlguifactory_p.h" 23 #include "kxmlguiclient.h" 24 #include "kxmlguibuilder.h" 30 #include <tqtextstream.h> 32 #include <tqdatetime.h> 33 #include <tqvariant.h> 35 #include <tdeaction.h> 37 #include <kinstance.h> 38 #include <tdeglobal.h> 39 #include <tdeshortcut.h> 40 #include <kstandarddirs.h> 41 #include <kkeydialog.h> 49 class KXMLGUIFactoryPrivate :
public BuildState
52 KXMLGUIFactoryPrivate()
58 m_rootNode =
new ContainerNode( 0L, TQString::null, 0L );
59 m_defaultMergingName = defaultMergingName;
60 tagActionList = actionList;
63 ~KXMLGUIFactoryPrivate()
70 m_stateStack.push( *
this );
75 BuildState::operator=( m_stateStack.pop() );
78 ContainerNode *m_rootNode;
80 TQString m_defaultMergingName;
85 TQString m_containerName;
90 TQPtrList<KXMLGUIClient> m_clients;
92 TQString tagActionList;
96 BuildStateStack m_stateStack;
99 TQString KXMLGUIFactory::readConfigFile(
const TQString &filename,
const TDEInstance *instance )
101 return readConfigFile( filename,
false, instance );
104 TQString KXMLGUIFactory::readConfigFile(
const TQString &filename,
bool never_null,
const TDEInstance *_instance )
109 if (!TQDir::isRelativePath(filename))
113 xml_file =
locate(
"data", TQString::fromLatin1(instance->
instanceName() +
'/' ) + filename);
114 if ( !TQFile::exists( xml_file ) )
115 xml_file =
locate(
"data", filename );
118 TQFile file( xml_file );
119 if ( !file.open( IO_ReadOnly ) )
121 kdError(240) <<
"No such XML file " << filename <<
endl;
123 return TQString::fromLatin1(
"<!DOCTYPE kpartgui>\n<kpartgui name=\"empty\">\n</kpartgui>" );
125 return TQString::null;
128 #if TQT_VERSION <= 0x030302 130 TQByteArray buffer(file.size() + 1);
131 buffer = file.readAll();
132 if(!buffer.isEmpty())
133 buffer[ buffer.size() - 1 ] =
'\0';
135 return TQString::null;
137 TQByteArray buffer(file.readAll());
139 return TQString::fromUtf8(buffer.data(), buffer.size());
142 bool KXMLGUIFactory::saveConfigFile(
const TQDomDocument& doc,
143 const TQString& filename,
const TDEInstance *_instance )
146 TQString xml_file(filename);
148 if (TQDir::isRelativePath(xml_file))
152 TQFile file( xml_file );
153 if ( !file.open( IO_WriteOnly ) )
155 kdError(240) <<
"Could not write to " << filename <<
endl;
160 TQTextStream ts(&file);
161 ts.setEncoding( TQTextStream::UnicodeUTF8 );
168 TQString KXMLGUIFactory::documentToXML(
const TQDomDocument& doc )
171 TQTextStream ts(&str, IO_WriteOnly);
172 ts.setEncoding( TQTextStream::UnicodeUTF8 );
177 TQString KXMLGUIFactory::elementToXML(
const TQDomElement& elem )
180 TQTextStream ts(&str, IO_WriteOnly);
181 ts.setEncoding( TQTextStream::UnicodeUTF8 );
188 TQDomNode n = node.firstChild();
189 while ( !n.isNull() )
191 if ( n.nodeType() == TQDomNode::CommentNode )
195 node.removeChild( tmp );
201 removeDOMComments( tmp );
207 : TQObject( parent, name )
209 d =
new KXMLGUIFactoryPrivate;
210 d->builder = builder;
214 d->builderContainerTags = d->builder->containerTags();
215 d->builderCustomTags = d->builder->customTags();
226 kdDebug(1002) <<
"KXMLGUIFactory::addClient( " << client <<
" )" <<
endl;
230 if ( client->
factory() == this )
240 d->guiClient = client;
243 if ( !d->m_clients.containsRef( client ) )
244 d->m_clients.append( client );
246 kdDebug(1002) <<
"XMLGUI client already added " << client <<
endl;
257 if ( doc.documentElement().isNull() )
260 TQDomElement docElement = doc.documentElement();
262 d->m_rootNode->index = -1;
266 d->clientName = docElement.attribute( d->attrName );
269 if ( d->clientBuilder )
271 d->clientBuilderContainerTags = d->clientBuilder->containerTags();
272 d->clientBuilderCustomTags = d->clientBuilder->customTags();
276 d->clientBuilderContainerTags.clear();
277 d->clientBuilderCustomTags.clear();
282 TQDomElement actionPropElement = docElement.namedItem( actionPropElementName ).toElement();
283 if ( actionPropElement.isNull() )
284 actionPropElement = docElement.namedItem( actionPropElementName.lower() ).toElement();
286 if ( !actionPropElement.isNull() )
287 applyActionProperties( actionPropElement );
289 BuildHelper( *d, d->m_rootNode ).build( docElement );
298 d->builder->finalizeGUI( d->guiClient );
301 d->BuildState::reset();
307 emit clientAdded( client );
312 const TQPtrList<KXMLGUIClient> *children = client->
childClients();
313 TQPtrListIterator<KXMLGUIClient> childIt( *children );
314 for (; childIt.current(); ++childIt )
323 kdDebug(1002) <<
"KXMLGUIFactory::removeClient( " << client <<
" )" <<
endl;
326 if ( !client || client->
factory() != this )
330 d->m_clients.removeRef( client );
335 const TQPtrList<KXMLGUIClient> *children = client->
childClients();
336 TQPtrListIterator<KXMLGUIClient> childIt( *children );
338 for (; childIt.current(); --childIt )
342 kdDebug(1002) <<
"KXMLGUIFactory::removeServant, calling removeRecursive" <<
endl;
348 d->guiClient = client;
349 d->clientName = client->
domDocument().documentElement().attribute( d->attrName );
358 if ( doc.documentElement().isNull() )
360 doc = client->
domDocument().cloneNode(
true ).toDocument();
364 d->m_rootNode->destruct( doc.documentElement(), *d );
366 d->builder->finalizeGUI( d->guiClient );
369 d->BuildState::reset();
376 emit clientRemoved( client );
388 d->m_containerName = containerName;
389 d->guiClient = client;
391 TQWidget *result = findRecursive( d->m_rootNode, useTagName );
394 d->m_containerName = TQString::null;
401 TQPtrList<TQWidget> KXMLGUIFactory::containers(
const TQString &tagName )
403 return findRecursive( d->m_rootNode, tagName );
408 d->m_rootNode->reset();
410 d->m_rootNode->clearChildren();
415 if ( containerName.isEmpty() )
418 ContainerNode *
container = d->m_rootNode->findContainer( containerName, useTagName );
423 ContainerNode *parent = container->parent;
429 parent->removeChild( container );
432 TQWidget *KXMLGUIFactory::findRecursive( KXMLGUI::ContainerNode *node,
bool tag )
434 if ( ( ( !tag && node->name == d->m_containerName ) ||
435 ( tag && node->tagName == d->m_containerName ) ) &&
436 ( !d->guiClient || node->client == d->guiClient ) )
437 return node->container;
439 TQPtrListIterator<ContainerNode> it( node->children );
440 for (; it.current(); ++it )
442 TQWidget *cont = findRecursive( it.current(), tag );
450 TQPtrList<TQWidget> KXMLGUIFactory::findRecursive( KXMLGUI::ContainerNode *node,
451 const TQString &tagName )
453 TQPtrList<TQWidget> res;
455 if ( node->tagName == tagName.lower() )
456 res.append( node->container );
458 TQPtrListIterator<KXMLGUI::ContainerNode> it( node->children );
459 for (; it.current(); ++it )
461 TQPtrList<TQWidget> lst = findRecursive( it.current(), tagName );
462 TQPtrListIterator<TQWidget> wit( lst );
463 for (; wit.current(); ++wit )
464 res.append( wit.current() );
470 void KXMLGUIFactory::plugActionList(
KXMLGUIClient *client,
const TQString &name,
471 const TQPtrList<TDEAction> &actionList )
474 d->guiClient = client;
475 d->actionListName = name;
476 d->actionList = actionList;
477 d->clientName = client->
domDocument().documentElement().attribute( d->attrName );
479 d->m_rootNode->plugActionList( *d );
481 d->BuildState::reset();
485 void KXMLGUIFactory::unplugActionList(
KXMLGUIClient *client,
const TQString &name )
488 d->guiClient = client;
489 d->actionListName = name;
490 d->clientName = client->
domDocument().documentElement().attribute( d->attrName );
492 d->m_rootNode->unplugActionList( *d );
494 d->BuildState::reset();
498 void KXMLGUIFactory::applyActionProperties(
const TQDomElement &actionPropElement )
502 for (TQDomNode n = actionPropElement.firstChild();
503 !n.isNull(); n = n.nextSibling() )
505 TQDomElement e = n.toElement();
506 if ( e.tagName().lower() != tagAction )
509 TDEAction *action = d->guiClient->action( e );
513 configureAction( action, e.attributes() );
517 void KXMLGUIFactory::configureAction(
TDEAction *action,
const TQDomNamedNodeMap &attributes )
519 for ( uint i = 0; i < attributes.length(); i++ )
521 TQDomAttr attr = attributes.item( i ).toAttr();
525 configureAction( action, attr );
529 void KXMLGUIFactory::configureAction(
TDEAction *action,
const TQDomAttr &attribute )
533 TQString attrName = attribute.name();
535 if ( attrName.lower() ==
"accel" )
536 attrName = attrShortcut;
538 TQVariant propertyValue;
540 TQVariant::Type propertyType = action->property( attrName.latin1() ).type();
542 if ( propertyType == TQVariant::Int )
543 propertyValue = TQVariant( attribute.value().toInt() );
544 else if ( propertyType == TQVariant::UInt )
545 propertyValue = TQVariant( attribute.value().toUInt() );
547 propertyValue = TQVariant( attribute.value() );
549 action->setProperty( attrName.latin1(), propertyValue );
555 KKeyDialog dlg( bAllowLetterShortcuts, tqt_dynamic_cast<TQWidget*>(parent()) );
556 TQPtrListIterator<KXMLGUIClient> it( d->m_clients );
558 while( (client=it.current()) !=0 )
561 if(!client->
xmlFile().isEmpty())
569 const TQString tagActionProp = TQString::fromLatin1(
"ActionProperties");
572 TQDomNode it = doc.documentElement().firstChild();
573 for( ; !it.isNull(); it = it.nextSibling() ) {
574 TQDomElement e = it.toElement();
575 if( e.tagName() == tagActionProp ) {
582 if( elem.isNull() ) {
583 elem = doc.createElement( tagActionProp );
584 doc.documentElement().appendChild( elem );
593 for( TQDomNode it = elem.firstChild(); !it.isNull(); it = it.nextSibling() ) {
594 TQDomElement e = it.toElement();
595 if( e.attribute( attrName ) == sName )
600 TQDomElement act_elem = elem.ownerDocument().createElement( tagAction );
601 act_elem.setAttribute( attrName, sName );
602 elem.appendChild( act_elem );
605 return TQDomElement();
608 void KXMLGUIFactory::virtual_hook(
int,
void* )
611 #include "kxmlguifactory.moc" void prepareXMLUnplug(TQWidget *)
A KXMLGUIClient can be used with KXMLGUIFactory to create a GUI from actions and an XML document...
TQString locateLocal(const char *type, const TQString &filename, const TDEInstance *instance=TDEGlobal::instance())
void setXMLGUIBuildDocument(const TQDomDocument &doc)
void removeClient(KXMLGUIClient *client)
Removes the GUI described by the client, by unplugging all provided actions and removing all owned co...
static void removeDOMComments(TQDomNode &node)
Removes all TQDomComment objects from the specified node and all its children.
KXMLGUIBuilder * clientBuilder() const
Retrieves the client's GUI builder or 0L if no client specific builder has been assigned via setClien...
void addClient(KXMLGUIClient *client)
Creates the GUI described by the TQDomDocument of the client, using the client's actions, and merges it with the previously created GUI.
kdbgstream kdError(int area=0)
TQCString instanceName() const
const TQPtrList< KXMLGUIClient > * childClients()
Retrieves a list of all child clients.
virtual TDEActionCollection * actionCollection() const
Retrieves the entire action collection for the GUI client.
kdbgstream kdDebug(int area=0)
void reset()
Use this method to free all memory allocated by the KXMLGUIFactory.
KXMLGUIFactory(KXMLGUIBuilder *builder, TQObject *parent=0, const char *name=0)
Constructs a KXMLGUIFactory.
Class to encapsulate user-driven action or event.
void setFactory(KXMLGUIFactory *factory)
This method is called by the KXMLGUIFactory as soon as the client is added to the KXMLGUIFactory's GU...
static TQDomElement findActionByName(TQDomElement &elem, const TQString &sName, bool create)
TQPtrList< KXMLGUIClient > clients() const
Returns a list of all clients currently added to this factory.
Abstract interface for a "GUI builder", used by the GUIFactory This interface is implemented by TDEMa...
bool configure(bool bSaveSettings=true)
Run the dialog and call commitChanges() if bSaveSettings is true.
static TDEInstance * instance()
static TQDomElement actionPropertiesElement(TQDomDocument &doc)
void resetContainer(const TQString &containerName, bool useTagName=false)
Use this method to free all memory allocated by the KXMLGUIFactory for a specific container...
Dialog for configuration of TDEActionCollection, TDEAccel, and TDEGlobalAccel.
static const TQString & staticQString(const char *str)
KXMLGUIFactory * factory() const
Retrieves a pointer to the KXMLGUIFactory this client is associated with (will return 0L if the clien...
virtual TQString xmlFile() const
This will return the name of the XML file as set by setXMLFile().
virtual TQDomDocument domDocument() const
TQWidget * container(const TQString &containerName, KXMLGUIClient *client, bool useTagName=false)
Use this method to get access to a container widget with the name specified with containerName and wh...
void beginXMLPlug(TQWidget *)
kndbgstream & endl(kndbgstream &s)
TQString locate(const char *type, const TQString &filename, const TDEInstance *instance=TDEGlobal::instance())
int configureShortcuts(bool bAllowLetterShortcuts=true, bool bSaveSettings=true)
Show a standard configure shortcut for every action in this factory.
TQDomDocument xmlguiBuildDocument() const
TQString name(StdAccel id)
~KXMLGUIFactory()
Destructor.
bool insert(TDEActionCollection *)
Insert an action collection, i.e.