|
|
|
/*
|
|
|
|
**************************************************************************
|
|
|
|
description
|
|
|
|
--------------------
|
|
|
|
copyright : (C) 2000-2001 by Andreas Zehender
|
|
|
|
email : zehender@kde.org
|
|
|
|
**************************************************************************
|
|
|
|
|
|
|
|
**************************************************************************
|
|
|
|
* *
|
|
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
|
|
* it under the terms of the GNU General Public License as published by *
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
|
|
* (at your option) any later version. *
|
|
|
|
* *
|
|
|
|
**************************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
#include "pmcompositeobject.h"
|
|
|
|
#include "pmxmlhelper.h"
|
|
|
|
#include "pmmemento.h"
|
|
|
|
#include "pmviewstructure.h"
|
|
|
|
|
|
|
|
#include <tqdom.h>
|
|
|
|
|
|
|
|
PMMetaObject* PMCompositeObject::s_pMetaObject = 0;
|
|
|
|
|
|
|
|
PMCompositeObject::PMCompositeObject( PMPart* part )
|
|
|
|
: Base( part )
|
|
|
|
{
|
|
|
|
m_pFirstChild = 0;
|
|
|
|
m_pLastChild = 0;
|
|
|
|
m_selectedChildren = 0;
|
|
|
|
m_bViewStructureChanged = true;
|
|
|
|
m_pViewStructure = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
PMCompositeObject::PMCompositeObject( const PMCompositeObject& c )
|
|
|
|
: Base( c )
|
|
|
|
{
|
|
|
|
m_pFirstChild = 0;
|
|
|
|
m_pLastChild = 0;
|
|
|
|
m_selectedChildren = 0;
|
|
|
|
m_bViewStructureChanged = true;
|
|
|
|
m_pViewStructure = 0;
|
|
|
|
|
|
|
|
PMObject* o = c.m_pFirstChild;
|
|
|
|
for( ; o; o = o->nextSibling( ) )
|
|
|
|
appendChild( o->copy( ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
PMCompositeObject::~PMCompositeObject( )
|
|
|
|
{
|
|
|
|
PMObject* tmp;
|
|
|
|
PMObject* next;
|
|
|
|
|
|
|
|
tmp = m_pFirstChild;
|
|
|
|
|
|
|
|
while( tmp )
|
|
|
|
{
|
|
|
|
next = tmp->m_pNextSibling;
|
|
|
|
delete tmp;
|
|
|
|
tmp = next;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( m_pViewStructure )
|
|
|
|
delete m_pViewStructure;
|
|
|
|
}
|
|
|
|
|
|
|
|
PMMetaObject* PMCompositeObject::tqmetaObject( ) const
|
|
|
|
{
|
|
|
|
if( !s_pMetaObject )
|
|
|
|
s_pMetaObject = new PMMetaObject( "CompositeObject", Base::tqmetaObject( ) );
|
|
|
|
return s_pMetaObject;
|
|
|
|
}
|
|
|
|
|
|
|
|
void PMCompositeObject::cleanUp( ) const
|
|
|
|
{
|
|
|
|
if( s_pMetaObject )
|
|
|
|
{
|
|
|
|
delete s_pMetaObject;
|
|
|
|
s_pMetaObject = 0;
|
|
|
|
}
|
|
|
|
Base::cleanUp( );
|
|
|
|
}
|
|
|
|
|
|
|
|
PMObject* PMCompositeObject::tqchildAt( uint index ) const
|
|
|
|
{
|
|
|
|
PMObject* tmp;
|
|
|
|
uint i = 0;
|
|
|
|
|
|
|
|
for( tmp = m_pFirstChild; tmp && ( i < index ); tmp = tmp->nextSibling( ) )
|
|
|
|
i++;
|
|
|
|
return tmp;
|
|
|
|
}
|
|
|
|
|
|
|
|
int PMCompositeObject::findChild( PMObject* o )
|
|
|
|
{
|
|
|
|
if( o->tqparent( ) != this )
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
PMObject* tmp;
|
|
|
|
int index = 0;
|
|
|
|
|
|
|
|
for( tmp = m_pFirstChild; tmp; tmp = tmp->nextSibling( ) )
|
|
|
|
{
|
|
|
|
if( tmp == o )
|
|
|
|
return index;
|
|
|
|
else
|
|
|
|
index++;
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool PMCompositeObject::insertChild( PMObject* o, int i )
|
|
|
|
{
|
|
|
|
if( i < 0 )
|
|
|
|
return appendChild( o );
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if( i == 0 )
|
|
|
|
{
|
|
|
|
if( canInsert( o, 0 ) )
|
|
|
|
{
|
|
|
|
o->m_pNextSibling = m_pFirstChild;
|
|
|
|
o->m_pPrevSibling = 0;
|
|
|
|
if( m_pFirstChild )
|
|
|
|
m_pFirstChild->m_pPrevSibling = o;
|
|
|
|
m_pFirstChild = o;
|
|
|
|
if( !m_pLastChild )
|
|
|
|
m_pLastChild = o;
|
|
|
|
o->m_pParent = this;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
PMObject* tmp = tqchildAt( ( uint ) ( i - 1 ) );
|
|
|
|
if( !tmp )
|
|
|
|
{
|
|
|
|
kdError( PMArea ) << "Index too big" << "\n";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( canInsert( o, tmp ) )
|
|
|
|
{
|
|
|
|
o->m_pPrevSibling = tmp;
|
|
|
|
o->m_pNextSibling = tmp->m_pNextSibling;
|
|
|
|
if( tmp->m_pNextSibling )
|
|
|
|
tmp->m_pNextSibling->m_pPrevSibling = o;
|
|
|
|
else
|
|
|
|
m_pLastChild = o;
|
|
|
|
tmp->m_pNextSibling = o;
|
|
|
|
o->m_pParent = this;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
childAdded( o );
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool PMCompositeObject::appendChild( PMObject* o )
|
|
|
|
{
|
|
|
|
if( canInsert( o, m_pLastChild ) )
|
|
|
|
{
|
|
|
|
o->m_pParent = this;
|
|
|
|
o->m_pPrevSibling = m_pLastChild;
|
|
|
|
o->m_pNextSibling = 0;
|
|
|
|
if( m_pLastChild )
|
|
|
|
m_pLastChild->m_pNextSibling = o;
|
|
|
|
else
|
|
|
|
m_pFirstChild = o;
|
|
|
|
m_pLastChild = o;
|
|
|
|
|
|
|
|
childAdded( o );
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool PMCompositeObject::insertChildAfter( PMObject* obj, PMObject* after )
|
|
|
|
{
|
|
|
|
if( canInsert( obj, after ) )
|
|
|
|
{
|
|
|
|
if( after->m_pParent == this )
|
|
|
|
{
|
|
|
|
obj->m_pParent = this;
|
|
|
|
obj->m_pPrevSibling = after;
|
|
|
|
obj->m_pNextSibling = after->m_pNextSibling;
|
|
|
|
if( after->m_pNextSibling )
|
|
|
|
after->m_pNextSibling->m_pPrevSibling = obj;
|
|
|
|
else
|
|
|
|
m_pLastChild = obj;
|
|
|
|
after->m_pNextSibling = obj;
|
|
|
|
|
|
|
|
childAdded( obj );
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
kdError( PMArea ) << "Object after is no child" << "\n";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool PMCompositeObject::insertChildBefore( PMObject* obj, PMObject* before )
|
|
|
|
{
|
|
|
|
if( before )
|
|
|
|
{
|
|
|
|
if( canInsert( obj, before->m_pPrevSibling ) )
|
|
|
|
{
|
|
|
|
if( before->m_pParent == this )
|
|
|
|
{
|
|
|
|
obj->m_pParent = this;
|
|
|
|
obj->m_pPrevSibling = before->m_pPrevSibling;
|
|
|
|
obj->m_pNextSibling = before;
|
|
|
|
if( before->m_pPrevSibling )
|
|
|
|
before->m_pPrevSibling->m_pNextSibling = obj;
|
|
|
|
else
|
|
|
|
m_pFirstChild = obj;
|
|
|
|
before->m_pPrevSibling = obj;
|
|
|
|
|
|
|
|
childAdded( obj );
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
kdError( PMArea ) << "Object before is no child" << "\n";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool PMCompositeObject::takeChild( PMObject* o )
|
|
|
|
{
|
|
|
|
if( ( PMObject* ) this == o->m_pParent )
|
|
|
|
{
|
|
|
|
// deselect the object and all child objects of o
|
|
|
|
if( o->isSelected( ) )
|
|
|
|
o->setSelected( false );
|
|
|
|
else if( o->selectedChildren( ) > 0 )
|
|
|
|
o->deselectChildren( );
|
|
|
|
|
|
|
|
// remove it, but do NOT delete it.
|
|
|
|
if( o->m_pPrevSibling )
|
|
|
|
o->m_pPrevSibling->m_pNextSibling = o->m_pNextSibling;
|
|
|
|
else
|
|
|
|
m_pFirstChild = o->m_pNextSibling;
|
|
|
|
if( o->m_pNextSibling )
|
|
|
|
o->m_pNextSibling->m_pPrevSibling = o->m_pPrevSibling;
|
|
|
|
else
|
|
|
|
m_pLastChild = o->m_pPrevSibling;
|
|
|
|
|
|
|
|
o->m_pParent = 0;
|
|
|
|
o->m_pPrevSibling = 0;
|
|
|
|
o->m_pNextSibling = 0;
|
|
|
|
|
|
|
|
childRemoved( o );
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
kdError( PMArea ) << "o is no child" << "\n";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool PMCompositeObject::takeChild( uint i )
|
|
|
|
{
|
|
|
|
PMObject* tmp = tqchildAt( i );
|
|
|
|
if( tmp )
|
|
|
|
return takeChild( tmp );
|
|
|
|
kdError( PMArea ) << "Index too big";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void PMCompositeObject::serialize( TQDomElement& e, TQDomDocument& doc ) const
|
|
|
|
{
|
|
|
|
PMObject* tmp;
|
|
|
|
|
|
|
|
for( tmp = m_pFirstChild; tmp; tmp = tmp->m_pNextSibling )
|
|
|
|
e.appendChild( tmp->serialize( doc ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
int PMCompositeObject::countChildren( ) const
|
|
|
|
{
|
|
|
|
int num = 0;
|
|
|
|
PMObject* tmp;
|
|
|
|
|
|
|
|
for( tmp = m_pFirstChild; tmp; tmp = tmp->m_pNextSibling )
|
|
|
|
num++;
|
|
|
|
return num;
|
|
|
|
}
|
|
|
|
|
|
|
|
void PMCompositeObject::adjustSelectedChildren( int num )
|
|
|
|
{
|
|
|
|
m_selectedChildren += num;
|
|
|
|
if( m_selectedChildren < 0 )
|
|
|
|
{
|
|
|
|
kdError( PMArea ) << "num too big in PMCompositeObject::adjustSelectedChildren( )\n";
|
|
|
|
m_selectedChildren = 0;
|
|
|
|
}
|
|
|
|
if( m_pParent )
|
|
|
|
m_pParent->adjustSelectedChildren( num );
|
|
|
|
}
|
|
|
|
|
|
|
|
void PMCompositeObject::deselectChildren( )
|
|
|
|
{
|
|
|
|
PMObject* tmp;
|
|
|
|
if( m_selectedChildren > 0 )
|
|
|
|
{
|
|
|
|
tmp = m_pFirstChild;
|
|
|
|
while( tmp && ( m_selectedChildren > 0 ) )
|
|
|
|
{
|
|
|
|
if( tmp->isSelected( ) )
|
|
|
|
tmp->setSelected( false );
|
|
|
|
else if( tmp->selectedChildren( ) > 0 )
|
|
|
|
tmp->deselectChildren( );
|
|
|
|
|
|
|
|
tmp = tmp->m_pNextSibling;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
PMViewStructure* PMCompositeObject::viewStructure( )
|
|
|
|
{
|
|
|
|
if( m_pViewStructure )
|
|
|
|
{
|
|
|
|
if( m_pViewStructure->parameterKey( ) != viewStructureParameterKey( ) )
|
|
|
|
{
|
|
|
|
// the default view structure or the parameters (detail level)
|
|
|
|
// have changed
|
|
|
|
m_bViewStructureChanged = true;
|
|
|
|
delete m_pViewStructure;
|
|
|
|
m_pViewStructure = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if( m_bViewStructureChanged )
|
|
|
|
{
|
|
|
|
PMViewStructure* dvs = defaultViewStructure( );
|
|
|
|
if( dvs )
|
|
|
|
if( dvs->parameterKey( ) == -1 ) // newly created view structure
|
|
|
|
dvs->setParameterKey( viewStructureParameterKey( ) );
|
|
|
|
|
|
|
|
if( isDefault( ) )
|
|
|
|
{
|
|
|
|
if( dvs )
|
|
|
|
{
|
|
|
|
if( m_pViewStructure )
|
|
|
|
{
|
|
|
|
if( *m_pViewStructure != *dvs )
|
|
|
|
{
|
|
|
|
delete m_pViewStructure;
|
|
|
|
m_pViewStructure = new PMViewStructure( dvs );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
m_pViewStructure = new PMViewStructure( dvs );
|
|
|
|
}
|
|
|
|
|
|
|
|
if( !m_pViewStructure )
|
|
|
|
kdError( PMArea ) << "isDefault( ) returned true, but no default view structure is provided\n";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if( dvs )
|
|
|
|
{
|
|
|
|
if( m_pViewStructure && ( *m_pViewStructure == *dvs ) )
|
|
|
|
{
|
|
|
|
delete m_pViewStructure;
|
|
|
|
m_pViewStructure = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
createViewStructure( );
|
|
|
|
if( m_pViewStructure )
|
|
|
|
m_pViewStructure->setParameterKey( viewStructureParameterKey( ) );
|
|
|
|
}
|
|
|
|
m_bViewStructureChanged = false;
|
|
|
|
}
|
|
|
|
return m_pViewStructure;
|
|
|
|
}
|
|
|
|
|
|
|
|
void PMCompositeObject::setViewStructureChanged( )
|
|
|
|
{
|
|
|
|
m_bViewStructureChanged = true;
|
|
|
|
if( m_pMemento )
|
|
|
|
m_pMemento->setViewStructureChanged( );
|
|
|
|
}
|
|
|
|
|