/* This file is part of the KDE libraries Copyright (C) 2001 Simon Hausmann <hausmann@kde.org> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __kxmlguifactory_p_h__ #define __kxmlguifactory_p_h__ #include <tqstringlist.h> #include <tqmap.h> #include <tqdom.h> #include <tqvaluestack.h> #include <kaction.h> class TQWidget; class KXMLGUIClient; class KXMLGUIBuilder; class KXMLGUIFactory; namespace KXMLGUI { struct BuildState; class KDEUI_EXPORT ActionList : public TQPtrList<KAction> { public: ActionList() {} ActionList( const TQPtrList<KAction> &rhs ) : TQPtrList<KAction>( rhs ) {} ActionList &operator=( const TQPtrList<KAction> &rhs ) { TQPtrList<KAction>::operator=( rhs ); return *this; } void plug( TQWidget *container, int index ) const; void unplug( TQWidget *container ) const; }; typedef TQPtrListIterator<KAction> ActionListIt; typedef TQMap< TQString, ActionList > ActionListMap; /* * This structure is used to know to which client certain actions and custom elements * (i.e. menu separators) belong. * We do not only use a ContainerClient per GUIClient but also per merging group. * * groupName : Used for grouped merging. Specifies the group name to which these actions/elements * belong to. * actionLists : maps from action list name to action list. * mergingName : The (named) merging point. * * A ContainerClient always belongs to a ContainerNode. */ struct ContainerClient { KXMLGUIClient *client; ActionList actions; TQValueList<int> customElements; TQString groupName; //is empty if no group client ActionListMap actionLists; TQString mergingName; }; typedef TQPtrList<ContainerClient> ContainerClientList; typedef TQPtrListIterator<ContainerClient> ContainerClientListIt; struct ContainerNode; struct MergingIndex { int value; // the actual index value, used as index for plug() or createContainer() calls TQString mergingName; // the name of the merging index (i.e. the name attribute of the // Merge or DefineGroup tag) TQString clientName; // the name of the client that defined this index }; typedef TQValueList<MergingIndex> MergingIndexList; /* * Here we store detailed information about a container, its clients (client=a guiclient having actions * plugged into the container), child nodes, naming information (tagname and name attribute) and * merging index information, to plug/insert new actions/items a the correct position. * * The builder variable is needed for using the proper GUIBuilder for destruction ( to use the same for * con- and destruction ). The builderCustomTags and builderContainerTags variables are cached values * of what the corresponding methods of the GUIBuilder which built the container return. The stringlists * is shared all over the place, so there's no need to worry about memory consumption for these * variables :-) * * The mergingIndices list contains the merging indices ;-) , as defined by <Merge>, <DefineGroup> * or by <ActionList> tags. The order of these index structures within the mergingIndices list * is (and has to be) identical with the order in the DOM tree. * * Beside the merging indices we have the "real" index of the container. It points to the next free * position. * (used when no merging index is used for a certain action, custom element or sub-container) */ struct KDEUI_EXPORT ContainerNode { ContainerNode( TQWidget *_container, const TQString &_tagName, const TQString &_name, ContainerNode *_parent = 0L, KXMLGUIClient *_client = 0L, KXMLGUIBuilder *_builder = 0L, int id = -1, const TQString &_mergingName = TQString::null, const TQString &groupName = TQString::null, const TQStringList &customTags = TQStringList(), const TQStringList &containerTags = TQStringList() ); ContainerNode *parent; KXMLGUIClient *client; KXMLGUIBuilder *builder; TQStringList builderCustomTags; TQStringList builderContainerTags; TQWidget *container; int containerId; TQString tagName; TQString name; TQString groupName; //is empty if the container is in no group ContainerClientList clients; TQPtrList<ContainerNode> children; int index; MergingIndexList mergingIndices; TQString mergingName; void clearChildren() { children.clear(); } void removeChild( ContainerNode *child ); MergingIndexList::Iterator findIndex( const TQString &name ); ContainerNode *findContainerNode( TQWidget *container ); ContainerNode *findContainer( const TQString &_name, bool tag ); ContainerNode *findContainer( const TQString &name, const TQString &tagName, const TQPtrList<TQWidget> *excludeList, KXMLGUIClient *currClient ); ContainerClient *findChildContainerClient( KXMLGUIClient *currentGUIClient, const TQString &groupName, const MergingIndexList::Iterator &mergingIdx ); void plugActionList( BuildState &state ); void plugActionList( BuildState &state, const MergingIndexList::Iterator &mergingIdxIt ); void unplugActionList( BuildState &state ); void unplugActionList( BuildState &state, const MergingIndexList::Iterator &mergingIdxIt ); void adjustMergingIndices( int offset, const MergingIndexList::Iterator &it ); bool destruct( TQDomElement element, BuildState &state ); void destructChildren( const TQDomElement &element, BuildState &state ); static TQDomElement findElementForChild( const TQDomElement &baseElement, ContainerNode *childNode ); void unplugActions( BuildState &state ); void unplugClient( ContainerClient *client ); void reset(); int calcMergingIndex( const TQString &mergingName, MergingIndexList::Iterator &it, BuildState &state, bool ignoreDefaultMergingIndex ); }; typedef TQPtrList<ContainerNode> ContainerNodeList; typedef TQPtrListIterator<ContainerNode> ContainerNodeListIt; class KDEUI_EXPORT BuildHelper { public: BuildHelper( BuildState &state, ContainerNode *node ); void build( const TQDomElement &element ); private: void processElement( const TQDomElement &element ); void processActionOrCustomElement( const TQDomElement &e, bool isActionTag ); bool processActionElement( const TQDomElement &e, int idx ); bool processCustomElement( const TQDomElement &e, int idx ); void processStateElement( const TQDomElement &element ); void processMergeElement( const TQString &tag, const TQString &name, const TQDomElement &e ); void processContainerElement( const TQDomElement &e, const TQString &tag, const TQString &name ); TQWidget *createContainer( TQWidget *parent, int index, const TQDomElement &element, int &id, KXMLGUIBuilder **builder ); int calcMergingIndex( const TQDomElement &element, MergingIndexList::Iterator &it, TQString &group ); TQStringList customTags; TQStringList containerTags; TQPtrList<TQWidget> containerList; ContainerClient *containerClient; bool ignoreDefaultMergingIndex; BuildState &m_state; ContainerNode *parentNode; }; struct KDEUI_EXPORT BuildState { BuildState() : guiClient( 0 ), builder( 0 ), clientBuilder( 0 ) {} void reset(); TQString clientName; TQString actionListName; ActionList actionList; KXMLGUIClient *guiClient; MergingIndexList::Iterator currentDefaultMergingIt; MergingIndexList::Iterator currentClientMergingIt; KXMLGUIBuilder *builder; TQStringList builderCustomTags; TQStringList builderContainerTags; KXMLGUIBuilder *clientBuilder; TQStringList clientBuilderCustomTags; TQStringList clientBuilderContainerTags; }; typedef TQValueStack<BuildState> BuildStateStack; } #endif /* vim: et sw=4 */