|
|
|
/***************************************************************************
|
|
|
|
* Copyright (C) 2004 by Alexander Dymo *
|
|
|
|
* cloudtemple@mskat.net *
|
|
|
|
* *
|
|
|
|
* This program 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 program 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 General Public License for more details. *
|
|
|
|
* *
|
|
|
|
* You should have received a copy of the GNU Library General Public *
|
|
|
|
* License along with this program; if not, write to the *
|
|
|
|
* Free Software Foundation, Inc., *
|
|
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
|
|
|
|
***************************************************************************/
|
|
|
|
#include "propertylist.h"
|
|
|
|
|
|
|
|
#include "property.h"
|
|
|
|
#include "multiproperty.h"
|
|
|
|
|
|
|
|
namespace PropertyLib{
|
|
|
|
|
|
|
|
PropertyList::PropertyList()
|
|
|
|
:TQObject(0, 0), m_propertyOwner(true)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
PropertyList::PropertyList(bool propertyOwner)
|
|
|
|
:TQObject(0, 0), m_propertyOwner(propertyOwner)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
PropertyList::~PropertyList()
|
|
|
|
{
|
|
|
|
clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
MultiProperty *PropertyList::operator[](const TQString &name)
|
|
|
|
{
|
|
|
|
if (m_list.contains(name))
|
|
|
|
return m_list[name];
|
|
|
|
else
|
|
|
|
return new MultiProperty(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
MultiProperty *PropertyList::property( const TQString &name )
|
|
|
|
{
|
|
|
|
if (m_list.contains(name))
|
|
|
|
return m_list[name];
|
|
|
|
else
|
|
|
|
return new MultiProperty(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
void PropertyList::addProperty(Property *property)
|
|
|
|
{
|
|
|
|
if (property == 0)
|
|
|
|
return;
|
|
|
|
MultiProperty *mp = 0;
|
|
|
|
if ( m_list.contains(property->name()) )
|
|
|
|
{
|
|
|
|
mp = m_list[property->name()];
|
|
|
|
mp->addProperty(property);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
mp = new MultiProperty(this, property);
|
|
|
|
m_list[property->name()] = mp;
|
|
|
|
addToGroup("", mp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void PropertyList::addProperty(const TQString &group, Property *property)
|
|
|
|
{
|
|
|
|
if (property == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
MultiProperty *mp = 0;
|
|
|
|
if (m_list.contains(property->name()))
|
|
|
|
{
|
|
|
|
mp = m_list[property->name()];
|
|
|
|
mp->addProperty(property);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
mp = new MultiProperty(this, property);
|
|
|
|
m_list[property->name()] = mp;
|
|
|
|
addToGroup(group, mp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void PropertyList::removeProperty(Property *property)
|
|
|
|
{
|
|
|
|
if (property == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (m_propertyOwner)
|
|
|
|
emit aboutToDeleteProperty(property);
|
|
|
|
|
|
|
|
MultiProperty *mp = m_list[property->name()];
|
|
|
|
TQString group = m_groupOfProperty[mp];
|
|
|
|
removeFromGroup(mp);
|
|
|
|
TQString pname = property->name();
|
|
|
|
mp->removeProperty(property);
|
|
|
|
if (m_propertyOwner)
|
|
|
|
delete property;
|
|
|
|
if (mp->list.count() == 0)
|
|
|
|
{
|
|
|
|
// tqWarning("rp: removing mp for %s itself", pname.ascii());
|
|
|
|
m_list.remove(pname);
|
|
|
|
delete mp;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
addToGroup(group, mp);
|
|
|
|
}
|
|
|
|
|
|
|
|
void PropertyList::removeProperty(const TQString &name)
|
|
|
|
{
|
|
|
|
if (m_list.contains(name))
|
|
|
|
{
|
|
|
|
TQString group = m_groupOfProperty[m_list[name]];
|
|
|
|
removeFromGroup(m_list[name]);
|
|
|
|
Property *property;
|
|
|
|
for (property = m_list[name]->list.first(); property; property = m_list[name]->list.next())
|
|
|
|
{
|
|
|
|
if (m_propertyOwner)
|
|
|
|
emit aboutToDeleteProperty(property);
|
|
|
|
|
|
|
|
m_list[property->name()]->removeProperty(property);
|
|
|
|
if (m_propertyOwner)
|
|
|
|
delete property;
|
|
|
|
}
|
|
|
|
if (m_list[name]->list.count() == 0)
|
|
|
|
{
|
|
|
|
// tqWarning("rp2: removing mp for %s itself", name.ascii());
|
|
|
|
delete m_list[name];
|
|
|
|
m_list.remove(name);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
addToGroup(group, m_list[name]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const TQValueList<TQPair<TQString, TQValueList<TQString> > >& PropertyList::propertiesOfGroup() const
|
|
|
|
{
|
|
|
|
return m_propertiesOfGroup;
|
|
|
|
}
|
|
|
|
|
|
|
|
const TQMap<MultiProperty*, TQString>& PropertyList::groupOfProperty() const
|
|
|
|
{
|
|
|
|
return m_groupOfProperty;
|
|
|
|
}
|
|
|
|
|
|
|
|
void PropertyList::addToGroup(const TQString &group, MultiProperty *property)
|
|
|
|
{
|
|
|
|
if (!property)
|
|
|
|
return;
|
|
|
|
|
|
|
|
//do not add same property to the group twice
|
|
|
|
if (m_groupOfProperty.contains(property) && (m_groupOfProperty[property] == group))
|
|
|
|
return;
|
|
|
|
|
|
|
|
TQPair<TQString, TQValueList<TQString> > *groupPair = 0;
|
|
|
|
for(TQValueList<TQPair<TQString, TQValueList<TQString> > >::iterator it = m_propertiesOfGroup.begin();
|
|
|
|
it != m_propertiesOfGroup.end(); ++it)
|
|
|
|
{
|
|
|
|
if ((*it).first == group)
|
|
|
|
{
|
|
|
|
groupPair = &(*it);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (groupPair == 0)
|
|
|
|
{
|
|
|
|
groupPair = new TQPair<TQString, TQValueList<TQString> >();
|
|
|
|
groupPair->first = group;
|
|
|
|
groupPair->second.append(property->name());
|
|
|
|
m_propertiesOfGroup.append(*groupPair);
|
|
|
|
m_groupOfProperty[property] = group;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
//check if group already contains property with the same name
|
|
|
|
if (!groupPair->second.contains(property->name()))
|
|
|
|
groupPair->second.append(property->name());
|
|
|
|
|
|
|
|
m_groupOfProperty[property] = group;
|
|
|
|
}
|
|
|
|
|
|
|
|
void PropertyList::removeFromGroup(MultiProperty *property)
|
|
|
|
{
|
|
|
|
TQString group = m_groupOfProperty[property];
|
|
|
|
// tqWarning("removeFromGroup group=%s", group.ascii());
|
|
|
|
|
|
|
|
for(TQValueList<TQPair<TQString, TQValueList<TQString> > >::iterator it = m_propertiesOfGroup.begin();
|
|
|
|
it != m_propertiesOfGroup.end(); ++it)
|
|
|
|
{
|
|
|
|
// tqWarning("removeFromGroup checking %s", (*it).first.ascii());
|
|
|
|
if ((*it).first == group)
|
|
|
|
{
|
|
|
|
// tqWarning("removeFromGroup removing %s", property->name().ascii());
|
|
|
|
(*it).second.remove(property->name());
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
m_groupOfProperty.remove(property);
|
|
|
|
}
|
|
|
|
|
|
|
|
void PropertyList::clear( )
|
|
|
|
{
|
|
|
|
for (TQMap<TQString, MultiProperty*>::iterator it = m_list.begin(); it != m_list.end(); ++it)
|
|
|
|
removeProperty(it.key());
|
|
|
|
}
|
|
|
|
|
|
|
|
bool PropertyList::contains( const TQString & name )
|
|
|
|
{
|
|
|
|
if (m_list.contains(name))
|
|
|
|
return true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQPtrList<Property> PropertyList::properties(const TQString &name)
|
|
|
|
{
|
|
|
|
if (m_list.contains(name))
|
|
|
|
return m_list[name]->list;
|
|
|
|
return TQPtrList<Property>();
|
|
|
|
}
|
|
|
|
|
|
|
|
PropertyList::Iterator PropertyList::begin()
|
|
|
|
{
|
|
|
|
return Iterator(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
PropertyList::Iterator PropertyList::end()
|
|
|
|
{
|
|
|
|
return Iterator(this, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
//PropertyList::Iterator class
|
|
|
|
|
|
|
|
PropertyList::Iterator::Iterator(PropertyList *list)
|
|
|
|
:m_list(list)
|
|
|
|
{
|
|
|
|
current = m_list->m_list.begin();
|
|
|
|
}
|
|
|
|
|
|
|
|
PropertyList::Iterator::Iterator(PropertyList *list, bool // end
|
|
|
|
)
|
|
|
|
:m_list(list)
|
|
|
|
{
|
|
|
|
current = m_list->m_list.end();
|
|
|
|
}
|
|
|
|
|
|
|
|
void PropertyList::Iterator::operator ++()
|
|
|
|
{
|
|
|
|
next();
|
|
|
|
}
|
|
|
|
|
|
|
|
void PropertyList::Iterator::operator ++(int)
|
|
|
|
{
|
|
|
|
next();
|
|
|
|
}
|
|
|
|
|
|
|
|
void PropertyList::Iterator::next()
|
|
|
|
{
|
|
|
|
++current;
|
|
|
|
}
|
|
|
|
|
|
|
|
MultiProperty *PropertyList::Iterator::operator *()
|
|
|
|
{
|
|
|
|
return data();
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString PropertyList::Iterator::key()
|
|
|
|
{
|
|
|
|
return current.key();
|
|
|
|
}
|
|
|
|
|
|
|
|
MultiProperty *PropertyList::Iterator::data()
|
|
|
|
{
|
|
|
|
return current.data();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool PropertyList::Iterator::operator !=(Iterator it)
|
|
|
|
{
|
|
|
|
return current != it.current;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// PropertyBuffer class
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
PropertyBuffer::PropertyBuffer( )
|
|
|
|
:PropertyList(false)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void PropertyBuffer::intersect(const PropertyList *list)
|
|
|
|
{
|
|
|
|
tqWarning("PropertyBuffer::intersect");
|
|
|
|
for (TQMap<TQString, MultiProperty*>::iterator it = m_list.begin(); it != m_list.end(); ++it)
|
|
|
|
{
|
|
|
|
// tqWarning("intersect:: for mp = %s", it.data()->name().ascii());
|
|
|
|
if (list->m_list.contains(it.key()))
|
|
|
|
{
|
|
|
|
/* tqWarning("intersect:: list contains %s", it.key().ascii());
|
|
|
|
if ( (*(it.data()) == *(list->m_list[it.key()])))
|
|
|
|
tqWarning("intersect:: equal properties");
|
|
|
|
else
|
|
|
|
tqWarning("intersect:: not equal properties");*/
|
|
|
|
if ( ((*it.data()) == *(list->m_list[it.key()]))
|
|
|
|
&& (list->m_groupOfProperty[list->m_list[it.key()]] == m_groupOfProperty[it.data()]) )
|
|
|
|
{
|
|
|
|
// tqWarning("intersect:: equal properties, adding");
|
|
|
|
it.data()->addProperty(list->m_list[it.key()]);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// tqWarning("intersect:: removing %s from intersection", it.key().ascii());
|
|
|
|
removeProperty(it.key());
|
|
|
|
}
|
|
|
|
connect(list, TQ_SIGNAL(propertyValueChanged(Property*)), this, TQ_SLOT(intersectedValueChanged(Property*)));
|
|
|
|
}
|
|
|
|
|
|
|
|
void PropertyBuffer::intersectedValueChanged(Property *property)
|
|
|
|
{
|
|
|
|
// tqWarning("PropertyBuffer::intersectedValueChanged");
|
|
|
|
TQString propertyName = property->name();
|
|
|
|
if (!contains(propertyName))
|
|
|
|
return;
|
|
|
|
|
|
|
|
MultiProperty mp(property);
|
|
|
|
if (mp == *m_list[propertyName])
|
|
|
|
{
|
|
|
|
Property *prop;
|
|
|
|
TQPtrList<Property> props = properties(propertyName);
|
|
|
|
for (prop = props.first(); prop; prop = props.next())
|
|
|
|
emit propertyValueChanged(prop);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
PropertyBuffer::PropertyBuffer(PropertyList *list)
|
|
|
|
:PropertyList(false)
|
|
|
|
{
|
|
|
|
//deep copy of m_list
|
|
|
|
for (TQMap<TQString, MultiProperty*>::const_iterator it = list->m_list.begin();
|
|
|
|
it != list->m_list.end(); ++it)
|
|
|
|
{
|
|
|
|
MultiProperty *mp = new MultiProperty(*it.data());
|
|
|
|
mp->m_propertyList = this;
|
|
|
|
addToGroup(list->m_groupOfProperty[it.data()], mp);
|
|
|
|
m_list[it.key()] = mp;
|
|
|
|
}
|
|
|
|
connect(list, TQ_SIGNAL(propertyValueChanged(Property*)), this, TQ_SLOT(intersectedValueChanged(Property*)));
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifndef PURE_QT
|
|
|
|
#include "propertylist.moc"
|
|
|
|
#endif
|