2014-11-13 01:04:59 +02:00
/* 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 .
*/
# include "kxmlguifactory_p.h"
# include "kxmlguiclient.h"
# include "kxmlguibuilder.h"
# include <kglobal.h>
# include <kdebug.h>
# include <kcomponentdata.h>
# include <ktoolbar.h>
2022-09-27 08:58:04 +03:00
# include <QWidget>
# include <assert.h>
2014-11-13 01:04:59 +02:00
using namespace KXMLGUI ;
void ActionList : : plug ( QWidget * container , int index ) const
{
QAction * before = 0L ; // Insert after end of widget's current actions (default).
if ( ( index < 0 ) | | ( index > container - > actions ( ) . count ( ) ) )
kWarning ( ) < < " Index " < < index < < " is not within range (0 - " < < container - > actions ( ) . count ( ) ;
else if ( index ! = container - > actions ( ) . count ( ) )
before = container - > actions ( ) . at ( index ) ; // Insert before indexed action.
foreach ( QAction * action , * this ) {
container - > insertAction ( before , action ) ;
// before = action; // BUG FIX: do not insert actions in reverse order.
}
}
void ActionList : : unplug ( QWidget * container ) const
{
foreach ( QAction * action , * this ) {
if ( container - > actions ( ) . contains ( action ) )
container - > removeAction ( action ) ;
}
}
ContainerNode : : ContainerNode ( QWidget * _container , const QString & _tagName ,
const QString & _name , ContainerNode * _parent ,
KXMLGUIClient * _client , KXMLGUIBuilder * _builder ,
QAction * _containerAction , const QString & _mergingName ,
const QString & _groupName , const QStringList & customTags ,
const QStringList & containerTags )
: parent ( _parent ) , client ( _client ) , builder ( _builder ) ,
builderCustomTags ( customTags ) , builderContainerTags ( containerTags ) ,
container ( _container ) , containerAction ( _containerAction ) , tagName ( _tagName ) , name ( _name ) ,
groupName ( _groupName ) , index ( 0 ) , mergingName ( _mergingName )
{
if ( parent )
parent - > children . append ( this ) ;
}
ContainerNode : : ~ ContainerNode ( )
{
qDeleteAll ( children ) ;
qDeleteAll ( clients ) ;
}
void ContainerNode : : removeChild ( ContainerNode * child )
{
MergingIndexList : : Iterator mergingIt = findIndex ( child - > mergingName ) ;
adjustMergingIndices ( - 1 , mergingIt ) ;
children . removeAll ( child ) ;
delete child ;
}
void ContainerNode : : removeChild ( QMutableListIterator < ContainerNode * > & childIterator )
{
MergingIndexList : : Iterator mergingIt = findIndex ( childIterator . peekNext ( ) - > mergingName ) ;
adjustMergingIndices ( - 1 , mergingIt ) ;
delete childIterator . next ( ) ;
childIterator . remove ( ) ;
}
/*
* Find a merging index with the given name . Used to find an index defined by < Merge name = " blah " / >
* or by a < DefineGroup name = " foo " / > tag .
*/
MergingIndexList : : Iterator ContainerNode : : findIndex ( const QString & name )
{
MergingIndexList : : Iterator it ( mergingIndices . begin ( ) ) ;
MergingIndexList : : Iterator end ( mergingIndices . end ( ) ) ;
for ( ; it ! = end ; + + it )
if ( ( * it ) . mergingName = = name )
return it ;
return it ;
}
/*
* Check if the given container widget is a child of this node and return the node structure
* if fonud .
*/
ContainerNode * ContainerNode : : findContainerNode ( QWidget * container )
{
foreach ( ContainerNode * child , children )
if ( child - > container = = container )
return child ;
return 0L ;
}
/*
* Find a container recursively with the given name . Either compares _name with the
* container ' s tag name or the value of the container ' s name attribute . Specified by
* the tag bool .
*/
ContainerNode * ContainerNode : : findContainer ( const QString & _name , bool tag )
{
if ( ( tag & & tagName = = _name ) | |
( ! tag & & name = = _name ) )
return this ;
foreach ( ContainerNode * child , children )
{
ContainerNode * res = child - > findContainer ( _name , tag ) ;
if ( res )
return res ;
}
return 0 ;
}
/*
* Finds a child container node ( not recursively ) with the given name and tagname . Explicitly
* leaves out container widgets specified in the exludeList . Also ensures that the containers
* belongs to currClient .
*/
ContainerNode * ContainerNode : : findContainer ( const QString & name , const QString & tagName ,
const QList < QWidget * > * excludeList ,
KXMLGUIClient * /*currClient*/ )
{
ContainerNode * res = 0L ;
ContainerNodeList : : ConstIterator nIt = children . constBegin ( ) ;
if ( ! name . isEmpty ( ) )
{
for ( ; nIt ! = children . constEnd ( ) ; + + nIt )
if ( ( * nIt ) - > name = = name & &
! excludeList - > contains ( ( * nIt ) - > container ) )
{
res = * nIt ;
break ;
}
return res ;
}
if ( ! tagName . isEmpty ( ) )
for ( ; nIt ! = children . constEnd ( ) ; + + nIt )
{
if ( ( * nIt ) - > tagName = = tagName & &
! excludeList - > contains ( ( * nIt ) - > container )
/*
* It is a bad idea to also compare the client , because
* we don ' t want to do so in situations like these :
*
* < MenuBar >
* < Menu >
* . . .
*
* other client :
* < MenuBar >
* < Menu >
* . . .
*
& & ( * nIt ) - > client = = currClient )
*/
)
{
res = * nIt ;
break ;
}
}
return res ;
}
ContainerClient * ContainerNode : : findChildContainerClient ( KXMLGUIClient * currentGUIClient ,
const QString & groupName ,
const MergingIndexList : : Iterator & mergingIdx )
{
if ( ! clients . isEmpty ( ) )
{
foreach ( ContainerClient * client , clients )
if ( client - > client = = currentGUIClient )
{
if ( groupName . isEmpty ( ) )
return client ;
if ( groupName = = client - > groupName )
return client ;
}
}
ContainerClient * client = new ContainerClient ;
client - > client = currentGUIClient ;
client - > groupName = groupName ;
if ( mergingIdx ! = mergingIndices . end ( ) )
client - > mergingName = ( * mergingIdx ) . mergingName ;
clients . append ( client ) ;
return client ;
}
void ContainerNode : : plugActionList ( BuildState & state )
{
MergingIndexList : : Iterator mIt ( mergingIndices . begin ( ) ) ;
MergingIndexList : : Iterator mEnd ( mergingIndices . end ( ) ) ;
for ( ; mIt ! = mEnd ; + + mIt )
plugActionList ( state , mIt ) ;
foreach ( ContainerNode * child , children )
child - > plugActionList ( state ) ;
}
void ContainerNode : : plugActionList ( BuildState & state , const MergingIndexList : : Iterator & mergingIdxIt )
{
2022-02-18 19:48:53 +02:00
static const QString tagActionList = QString : : fromLatin1 ( " actionlist " ) ;
2014-11-13 01:04:59 +02:00
MergingIndex mergingIdx = * mergingIdxIt ;
QString k ( mergingIdx . mergingName ) ;
if ( k . indexOf ( tagActionList ) = = - 1 )
return ;
k = k . mid ( tagActionList . length ( ) ) ;
if ( mergingIdx . clientName ! = state . clientName )
return ;
if ( k ! = state . actionListName )
return ;
ContainerClient * client = findChildContainerClient ( state . guiClient ,
QString ( ) ,
mergingIndices . end ( ) ) ;
client - > actionLists . insert ( k , state . actionList ) ;
state . actionList . plug ( container , mergingIdx . value ) ;
adjustMergingIndices ( state . actionList . count ( ) , mergingIdxIt ) ;
}
void ContainerNode : : unplugActionList ( BuildState & state )
{
MergingIndexList : : Iterator mIt ( mergingIndices . begin ( ) ) ;
MergingIndexList : : Iterator mEnd ( mergingIndices . end ( ) ) ;
for ( ; mIt ! = mEnd ; + + mIt )
unplugActionList ( state , mIt ) ;
foreach ( ContainerNode * child , children )
child - > unplugActionList ( state ) ;
}
void ContainerNode : : unplugActionList ( BuildState & state , const MergingIndexList : : Iterator & mergingIdxIt )
{
2022-02-18 19:48:53 +02:00
static const QString tagActionList = QString : : fromLatin1 ( " actionlist " ) ;
2014-11-13 01:04:59 +02:00
MergingIndex mergingIdx = * mergingIdxIt ;
QString k = mergingIdx . mergingName ;
if ( k . indexOf ( tagActionList ) = = - 1 )
return ;
k = k . mid ( tagActionList . length ( ) ) ;
if ( mergingIdx . clientName ! = state . clientName )
return ;
if ( k ! = state . actionListName )
return ;
ContainerClient * client = findChildContainerClient ( state . guiClient ,
QString ( ) ,
mergingIndices . end ( ) ) ;
ActionListMap : : Iterator lIt ( client - > actionLists . find ( k ) ) ;
if ( lIt = = client - > actionLists . end ( ) )
return ;
lIt . value ( ) . unplug ( container ) ;
adjustMergingIndices ( - int ( lIt . value ( ) . count ( ) ) , mergingIdxIt ) ;
client - > actionLists . erase ( lIt ) ;
}
void ContainerNode : : adjustMergingIndices ( int offset ,
const MergingIndexList : : Iterator & it )
{
MergingIndexList : : Iterator mergingIt = it ;
MergingIndexList : : Iterator mergingEnd = mergingIndices . end ( ) ;
for ( ; mergingIt ! = mergingEnd ; + + mergingIt )
( * mergingIt ) . value + = offset ;
index + = offset ;
}
bool ContainerNode : : destruct ( QDomElement element , BuildState & state ) //krazy:exclude=passbyvalue (this is correct QDom usage, and a ref wouldn't allow passing doc.documentElement() as argument)
{
destructChildren ( element , state ) ;
unplugActions ( state ) ;
// remove all merging indices the client defined
QMutableListIterator < MergingIndex > cmIt = mergingIndices ;
while ( cmIt . hasNext ( ) )
if ( cmIt . next ( ) . clientName = = state . clientName )
cmIt . remove ( ) ;
// ### check for merging index count, too?
if ( clients . count ( ) = = 0 & & children . count ( ) = = 0 & & container & &
client = = state . guiClient )
{
QWidget * parentContainer = 0L ;
if ( parent & & parent - > container )
parentContainer = parent - > container ;
assert ( builder ) ;
builder - > removeContainer ( container , parentContainer , element , containerAction ) ;
client = 0L ;
return true ;
}
if ( client = = state . guiClient )
client = 0L ;
return false ;
}
void ContainerNode : : destructChildren ( const QDomElement & element , BuildState & state )
{
QMutableListIterator < ContainerNode * > childIt = children ;
while ( childIt . hasNext ( ) )
{
ContainerNode * childNode = childIt . peekNext ( ) ;
QDomElement childElement = findElementForChild ( element , childNode ) ;
// destruct returns true in case the container really got deleted
if ( childNode - > destruct ( childElement , state ) )
removeChild ( childIt ) ;
else
childIt . next ( ) ;
}
}
QDomElement ContainerNode : : findElementForChild ( const QDomElement & baseElement ,
ContainerNode * childNode )
{
2022-02-18 19:48:53 +02:00
static const QString attrName = QString : : fromLatin1 ( " name " ) ;
2014-11-13 01:04:59 +02:00
// ### slow
for ( QDomNode n = baseElement . firstChild ( ) ; ! n . isNull ( ) ;
n = n . nextSibling ( ) )
{
QDomElement e = n . toElement ( ) ;
if ( e . tagName ( ) . toLower ( ) = = childNode - > tagName & &
e . attribute ( attrName ) = = childNode - > name )
return e ;
}
return QDomElement ( ) ;
}
void ContainerNode : : unplugActions ( BuildState & state )
{
if ( ! container )
return ;
QMutableListIterator < ContainerClient * > clientIt ( clients ) ;
/*
Disabled because it means in KToolBar : : saveState isHidden is always true then ,
which is clearly wrong .
if ( clients . count ( ) = = 1 & & clientIt . current ( ) - > client = = client & &
client = = state . guiClient )
container - > hide ( ) ; // this container is going to die, that's for sure.
// in this case let's just hide it, which makes the
// destruction faster
*/
while ( clientIt . hasNext ( ) )
//only unplug the actions of the client we want to remove, as the container might be owned
//by a different client
if ( clientIt . peekNext ( ) - > client = = state . guiClient )
{
unplugClient ( clientIt . peekNext ( ) ) ;
delete clientIt . next ( ) ;
clientIt . remove ( ) ;
}
else
clientIt . next ( ) ;
}
void ContainerNode : : unplugClient ( ContainerClient * client )
{
2022-02-18 19:48:53 +02:00
static const QString tagActionList = QString : : fromLatin1 ( " actionlist " ) ;
2014-11-13 01:04:59 +02:00
assert ( builder ) ;
// now quickly remove all custom elements (i.e. separators) and unplug all actions
QList < QAction * > : : ConstIterator custIt = client - > customElements . constBegin ( ) ;
QList < QAction * > : : ConstIterator custEnd = client - > customElements . constEnd ( ) ;
for ( ; custIt ! = custEnd ; + + custIt )
builder - > removeCustomElement ( container , * custIt ) ;
KToolBar * bar = qobject_cast < KToolBar * > ( container ) ;
if ( bar ) {
bar - > removeXMLGUIClient ( client - > client ) ;
}
client - > actions . unplug ( container ) ;
// now adjust all merging indices
MergingIndexList : : Iterator mergingIt = findIndex ( client - > mergingName ) ;
adjustMergingIndices ( - int ( client - > actions . count ( )
+ client - > customElements . count ( ) ) ,
mergingIt ) ;
// unplug all actionslists
ActionListMap : : ConstIterator alIt = client - > actionLists . constBegin ( ) ;
ActionListMap : : ConstIterator alEnd = client - > actionLists . constEnd ( ) ;
for ( ; alIt ! = alEnd ; + + alIt )
{
alIt . value ( ) . unplug ( container ) ;
// construct the merging index key (i.e. like named merging) , find the
// corresponding merging index and adjust all indices
QString mergingKey = alIt . key ( ) ;
mergingKey . prepend ( tagActionList ) ;
MergingIndexList : : Iterator mIt = findIndex ( mergingKey ) ;
if ( mIt = = mergingIndices . end ( ) )
continue ;
adjustMergingIndices ( - int ( alIt . value ( ) . count ( ) ) , mIt ) ;
// remove the actionlists' merging index
// ### still needed? we clean up below anyway?
mergingIndices . erase ( mIt ) ;
}
}
void ContainerNode : : reset ( )
{
foreach ( ContainerNode * child , children )
child - > reset ( ) ;
if ( client )
client - > setFactory ( 0L ) ;
}
int ContainerNode : : calcMergingIndex ( const QString & mergingName ,
MergingIndexList : : Iterator & it ,
BuildState & state ,
bool ignoreDefaultMergingIndex )
{
MergingIndexList : : Iterator mergingIt ;
if ( mergingName . isEmpty ( ) )
mergingIt = findIndex ( state . clientName ) ;
else
mergingIt = findIndex ( mergingName ) ;
MergingIndexList : : Iterator mergingEnd = mergingIndices . end ( ) ;
it = mergingEnd ;
if ( ( mergingIt = = mergingEnd & & state . currentDefaultMergingIt = = mergingEnd ) | |
ignoreDefaultMergingIndex )
return index ;
if ( mergingIt ! = mergingEnd )
it = mergingIt ;
else
it = state . currentDefaultMergingIt ;
return ( * it ) . value ;
}
int BuildHelper : : calcMergingIndex ( const QDomElement & element , MergingIndexList : : Iterator & it , QString & group )
{
2022-02-18 19:48:53 +02:00
static const QString attrGroup = QString : : fromLatin1 ( " group " ) ;
2014-11-13 01:04:59 +02:00
bool haveGroup = false ;
group = element . attribute ( attrGroup ) ;
if ( ! group . isEmpty ( ) ) {
group . prepend ( attrGroup ) ;
haveGroup = true ;
}
int idx ;
if ( haveGroup )
idx = parentNode - > calcMergingIndex ( group , it , m_state , ignoreDefaultMergingIndex ) ;
else if ( m_state . currentClientMergingIt = = parentNode - > mergingIndices . end ( ) )
idx = parentNode - > index ;
else
idx = ( * m_state . currentClientMergingIt ) . value ;
return idx ;
}
BuildHelper : : BuildHelper ( BuildState & state , ContainerNode * node )
: containerClient ( 0 ) , ignoreDefaultMergingIndex ( false ) , m_state ( state ) ,
parentNode ( node )
{
2022-02-18 19:48:53 +02:00
static const QString defaultMergingName = QString : : fromLatin1 ( " <default> " ) ;
2014-11-13 01:04:59 +02:00
// create a list of supported container and custom tags
customTags = m_state . builderCustomTags ;
containerTags = m_state . builderContainerTags ;
if ( parentNode - > builder ! = m_state . builder )
{
customTags + = parentNode - > builderCustomTags ;
containerTags + = parentNode - > builderContainerTags ;
}
if ( m_state . clientBuilder ) {
customTags = m_state . clientBuilderCustomTags + customTags ;
containerTags = m_state . clientBuilderContainerTags + containerTags ;
}
m_state . currentDefaultMergingIt = parentNode - > findIndex ( defaultMergingName ) ;
parentNode - > calcMergingIndex ( QString ( ) , m_state . currentClientMergingIt ,
m_state , /*ignoreDefaultMergingIndex*/ false ) ;
}
void BuildHelper : : build ( const QDomElement & element )
{
for ( QDomNode n = element . firstChild ( ) ; ! n . isNull ( ) ; n = n . nextSibling ( ) )
{
QDomElement e = n . toElement ( ) ;
if ( e . isNull ( ) ) continue ;
processElement ( e ) ;
}
}
void BuildHelper : : processElement ( const QDomElement & e )
{
// some often used QStrings
2022-02-18 19:48:53 +02:00
static const QString tagAction = QString : : fromLatin1 ( " action " ) ;
static const QString tagMerge = QString : : fromLatin1 ( " merge " ) ;
static const QString tagState = QString : : fromLatin1 ( " state " ) ;
static const QString tagDefineGroup = QString : : fromLatin1 ( " definegroup " ) ;
static const QString tagActionList = QString : : fromLatin1 ( " actionlist " ) ;
static const QString attrName = QString : : fromLatin1 ( " name " ) ;
2014-11-13 01:04:59 +02:00
QString tag ( e . tagName ( ) . toLower ( ) ) ;
QString currName ( e . attribute ( attrName ) ) ;
bool isActionTag = ( tag = = tagAction ) ;
if ( isActionTag | | customTags . indexOf ( tag ) ! = - 1 )
processActionOrCustomElement ( e , isActionTag ) ;
else if ( containerTags . indexOf ( tag ) ! = - 1 )
processContainerElement ( e , tag , currName ) ;
else if ( tag = = tagMerge | | tag = = tagDefineGroup | | tag = = tagActionList )
processMergeElement ( tag , currName , e ) ;
else if ( tag = = tagState )
processStateElement ( e ) ;
}
void BuildHelper : : processActionOrCustomElement ( const QDomElement & e , bool isActionTag )
{
if ( ! parentNode - > container )
return ;
MergingIndexList : : Iterator it ( m_state . currentClientMergingIt ) ;
QString group ;
int idx = calcMergingIndex ( e , it , group ) ;
containerClient = parentNode - > findChildContainerClient ( m_state . guiClient , group , it ) ;
bool guiElementCreated = false ;
if ( isActionTag )
guiElementCreated = processActionElement ( e , idx ) ;
else
guiElementCreated = processCustomElement ( e , idx ) ;
if ( guiElementCreated )
// adjust any following merging indices and the current running index for the container
parentNode - > adjustMergingIndices ( 1 , it ) ;
}
bool BuildHelper : : processActionElement ( const QDomElement & e , int idx )
{
assert ( m_state . guiClient ) ;
// look up the action and plug it in
QAction * action = m_state . guiClient - > action ( e ) ;
//kDebug(260) << "BuildHelper::processActionElement " << e.attribute( "name" ) << " -> " << action << " (in " << m_state.guiClient->actionCollection() << ")";
if ( ! action )
return false ;
QAction * before = 0L ;
if ( idx > = 0 & & idx < parentNode - > container - > actions ( ) . count ( ) )
before = parentNode - > container - > actions ( ) [ idx ] ;
parentNode - > container - > insertAction ( before , action ) ;
// save a reference to the plugged action, in order to properly unplug it afterwards.
containerClient - > actions . append ( action ) ;
return true ;
}
bool BuildHelper : : processCustomElement ( const QDomElement & e , int idx )
{
assert ( parentNode - > builder ) ;
QAction * action = parentNode - > builder - > createCustomElement ( parentNode - > container , idx , e ) ;
if ( ! action )
return false ;
containerClient - > customElements . append ( action ) ;
return true ;
}
void BuildHelper : : processStateElement ( const QDomElement & element )
{
QString stateName = element . attribute ( " name " ) ;
if ( stateName . isNull ( ) | | ! stateName . length ( ) ) return ;
for ( QDomNode n = element . firstChild ( ) ; ! n . isNull ( ) ; n = n . nextSibling ( ) )
{
QDomElement e = n . toElement ( ) ;
if ( e . isNull ( ) ) continue ;
QString tagName = e . tagName ( ) . toLower ( ) ;
if ( tagName ! = " enable " & & tagName ! = " disable " )
continue ;
bool processingActionsToEnable = ( tagName = = " enable " ) ;
// process action names
for ( QDomNode n2 = n . firstChild ( ) ; ! n2 . isNull ( ) ; n2 = n2 . nextSibling ( ) )
{
QDomElement actionEl = n2 . toElement ( ) ;
if ( actionEl . tagName ( ) . toLower ( ) ! = " action " ) continue ;
QString actionName = actionEl . attribute ( " name " ) ;
if ( actionName . isEmpty ( ) ) return ;
if ( processingActionsToEnable )
m_state . guiClient - > addStateActionEnabled ( stateName , actionName ) ;
else
m_state . guiClient - > addStateActionDisabled ( stateName , actionName ) ;
}
}
}
void BuildHelper : : processMergeElement ( const QString & tag , const QString & name , const QDomElement & e )
{
2022-02-18 19:48:53 +02:00
static const QString tagDefineGroup = QString : : fromLatin1 ( " definegroup " ) ;
static const QString tagActionList = QString : : fromLatin1 ( " actionlist " ) ;
static const QString defaultMergingName = QString : : fromLatin1 ( " <default> " ) ;
static const QString attrGroup = QString : : fromLatin1 ( " group " ) ;
2014-11-13 01:04:59 +02:00
QString mergingName ( name ) ;
if ( mergingName . isEmpty ( ) )
{
if ( tag = = tagDefineGroup )
{
2023-06-09 23:43:20 +03:00
kError ( ) < < " cannot define group without name! " ;
2014-11-13 01:04:59 +02:00
return ;
}
if ( tag = = tagActionList )
{
2023-06-09 23:43:20 +03:00
kError ( ) < < " cannot define actionlist without name! " ;
2014-11-13 01:04:59 +02:00
return ;
}
mergingName = defaultMergingName ;
}
if ( tag = = tagDefineGroup )
mergingName . prepend ( attrGroup ) ; //avoid possible name clashes by prepending
// "group" to group definitions
else if ( tag = = tagActionList )
mergingName . prepend ( tagActionList ) ;
if ( parentNode - > findIndex ( mergingName ) ! = parentNode - > mergingIndices . end ( ) )
return ; //do not allow the redefinition of merging indices!
MergingIndexList : : Iterator mIt ( parentNode - > mergingIndices . end ( ) ) ;
QString group ( e . attribute ( attrGroup ) ) ;
if ( ! group . isEmpty ( ) )
group . prepend ( attrGroup ) ;
// calculate the index of the new merging index. Usually this does not need any calculation,
// we just want the last available index (i.e. append) . But in case the <Merge> tag appears
// "inside" another <Merge> tag from a previously build client, then we have to use the
// "parent's" index. That's why we call calcMergingIndex here.
MergingIndex newIdx ;
newIdx . value = parentNode - > calcMergingIndex ( group , mIt , m_state , ignoreDefaultMergingIndex ) ;
newIdx . mergingName = mergingName ;
newIdx . clientName = m_state . clientName ;
// if that merging index is "inside" another one, then append it right after the "parent" .
if ( mIt ! = parentNode - > mergingIndices . end ( ) )
parentNode - > mergingIndices . insert ( + + mIt , newIdx ) ;
else
parentNode - > mergingIndices . append ( newIdx ) ;
if ( mergingName = = defaultMergingName )
ignoreDefaultMergingIndex = true ;
// re-calculate the running default and client merging indices.
m_state . currentDefaultMergingIt = parentNode - > findIndex ( defaultMergingName ) ;
parentNode - > calcMergingIndex ( QString ( ) , m_state . currentClientMergingIt ,
m_state , ignoreDefaultMergingIndex ) ;
}
void BuildHelper : : processContainerElement ( const QDomElement & e , const QString & tag ,
const QString & name )
{
2022-02-18 19:48:53 +02:00
static const QString defaultMergingName = QString : : fromLatin1 ( " <default> " ) ;
2014-11-13 01:04:59 +02:00
ContainerNode * containerNode = parentNode - > findContainer ( name , tag ,
& containerList ,
m_state . guiClient ) ;
if ( ! containerNode )
{
MergingIndexList : : Iterator it ( m_state . currentClientMergingIt ) ;
QString group ;
int idx = calcMergingIndex ( e , it , group ) ;
QAction * containerAction ;
KXMLGUIBuilder * builder ;
QWidget * container = createContainer ( parentNode - > container , idx , e , containerAction , & builder ) ;
// no container? (probably some <text> tag or so ;-)
if ( ! container )
return ;
parentNode - > adjustMergingIndices ( 1 , it ) ;
assert ( ! parentNode - > findContainerNode ( container ) ) ;
containerList . append ( container ) ;
QString mergingName ;
if ( it ! = parentNode - > mergingIndices . end ( ) )
mergingName = ( * it ) . mergingName ;
QStringList cusTags = m_state . builderCustomTags ;
QStringList conTags = m_state . builderContainerTags ;
if ( builder ! = m_state . builder )
{
cusTags = m_state . clientBuilderCustomTags ;
conTags = m_state . clientBuilderContainerTags ;
}
containerNode = new ContainerNode ( container , tag , name , parentNode ,
m_state . guiClient , builder , containerAction ,
mergingName , group , cusTags , conTags ) ;
} else {
if ( tag = = QLatin1String ( " toolbar " ) ) {
KToolBar * bar = qobject_cast < KToolBar * > ( containerNode - > container ) ;
if ( bar ) {
if ( m_state . guiClient & & ! m_state . guiClient - > xmlFile ( ) . isEmpty ( ) )
bar - > addXMLGUIClient ( m_state . guiClient ) ;
} else {
kWarning ( ) < < " toolbar container is not a KToolBar " ;
}
}
}
BuildHelper ( m_state , containerNode ) . build ( e ) ;
// and re-calculate running values, for better performance
m_state . currentDefaultMergingIt = parentNode - > findIndex ( defaultMergingName ) ;
parentNode - > calcMergingIndex ( QString ( ) , m_state . currentClientMergingIt ,
m_state , ignoreDefaultMergingIndex ) ;
}
QWidget * BuildHelper : : createContainer ( QWidget * parent , int index ,
const QDomElement & element , QAction * & containerAction ,
KXMLGUIBuilder * * builder )
{
QWidget * res = 0L ;
if ( m_state . clientBuilder )
{
res = m_state . clientBuilder - > createContainer ( parent , index , element , containerAction ) ;
if ( res )
{
* builder = m_state . clientBuilder ;
return res ;
}
}
KComponentData oldInstance = m_state . builder - > builderComponentData ( ) ;
KXMLGUIClient * oldClient = m_state . builder - > builderClient ( ) ;
m_state . builder - > setBuilderClient ( m_state . guiClient ) ;
res = m_state . builder - > createContainer ( parent , index , element , containerAction ) ;
m_state . builder - > setBuilderComponentData ( oldInstance ) ;
m_state . builder - > setBuilderClient ( oldClient ) ;
if ( res )
* builder = m_state . builder ;
return res ;
}
void BuildState : : reset ( )
{
clientName . clear ( ) ;
actionListName . clear ( ) ;
actionList . clear ( ) ;
guiClient = 0 ;
clientBuilder = 0 ;
currentDefaultMergingIt = currentClientMergingIt = MergingIndexList : : Iterator ( ) ;
}
/* vim: et sw=4
*/