You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdevelop/lib/widgets/propeditor/propertylist.cpp

370 lines
10 KiB

/***************************************************************************
* 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()
:QObject(0, 0), m_propertyOwner(true)
{
}
PropertyList::PropertyList(bool propertyOwner)
:QObject(0, 0), m_propertyOwner(propertyOwner)
{
}
PropertyList::~PropertyList()
{
clear();
}
MultiProperty *PropertyList::operator[](const QString &name)
{
if (m_list.contains(name))
return m_list[name];
else
return new MultiProperty(this);
}
MultiProperty *PropertyList::property( const QString &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 QString &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()];
QString group = m_groupOfProperty[mp];
removeFromGroup(mp);
QString pname = property->name();
mp->removeProperty(property);
if (m_propertyOwner)
delete property;
if (mp->list.count() == 0)
{
// qWarning("rp: removing mp for %s itself", pname.ascii());
m_list.remove(pname);
delete mp;
}
else
addToGroup(group, mp);
}
void PropertyList::removeProperty(const QString &name)
{
if (m_list.contains(name))
{
QString 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)
{
// qWarning("rp2: removing mp for %s itself", name.ascii());
delete m_list[name];
m_list.remove(name);
}
else
{
addToGroup(group, m_list[name]);
}
}
}
const QValueList<QPair<QString, QValueList<QString> > >& PropertyList::propertiesOfGroup() const
{
return m_propertiesOfGroup;
}
const QMap<MultiProperty*, QString>& PropertyList::groupOfProperty() const
{
return m_groupOfProperty;
}
void PropertyList::addToGroup(const QString &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;
QPair<QString, QValueList<QString> > *groupPair = 0;
for(QValueList<QPair<QString, QValueList<QString> > >::iterator it = m_propertiesOfGroup.begin();
it != m_propertiesOfGroup.end(); ++it)
{
if ((*it).first == group)
{
groupPair = &(*it);
break;
}
}
if (groupPair == 0)
{
groupPair = new QPair<QString, QValueList<QString> >();
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)
{
QString group = m_groupOfProperty[property];
// qWarning("removeFromGroup group=%s", group.ascii());
for(QValueList<QPair<QString, QValueList<QString> > >::iterator it = m_propertiesOfGroup.begin();
it != m_propertiesOfGroup.end(); ++it)
{
// qWarning("removeFromGroup checking %s", (*it).first.ascii());
if ((*it).first == group)
{
// qWarning("removeFromGroup removing %s", property->name().ascii());
(*it).second.remove(property->name());
break;
}
}
m_groupOfProperty.remove(property);
}
void PropertyList::clear( )
{
for (QMap<QString, MultiProperty*>::iterator it = m_list.begin(); it != m_list.end(); ++it)
removeProperty(it.key());
}
bool PropertyList::contains( const QString & name )
{
if (m_list.contains(name))
return true;
return false;
}
QPtrList<Property> PropertyList::properties(const QString &name)
{
if (m_list.contains(name))
return m_list[name]->list;
return QPtrList<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();
}
QString 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)
{
qWarning("PropertyBuffer::intersect");
for (QMap<QString, MultiProperty*>::iterator it = m_list.begin(); it != m_list.end(); ++it)
{
// qWarning("intersect:: for mp = %s", it.data()->name().ascii());
if (list->m_list.contains(it.key()))
{
/* qWarning("intersect:: list contains %s", it.key().ascii());
if ( (*(it.data()) == *(list->m_list[it.key()])))
qWarning("intersect:: equal properties");
else
qWarning("intersect:: not equal properties");*/
if ( ((*it.data()) == *(list->m_list[it.key()]))
&& (list->m_groupOfProperty[list->m_list[it.key()]] == m_groupOfProperty[it.data()]) )
{
// qWarning("intersect:: equal properties, adding");
it.data()->addProperty(list->m_list[it.key()]);
continue;
}
}
// qWarning("intersect:: removing %s from intersection", it.key().ascii());
removeProperty(it.key());
}
connect(list, SIGNAL(propertyValueChanged(Property*)), this, SLOT(intersectedValueChanged(Property*)));
}
void PropertyBuffer::intersectedValueChanged(Property *property)
{
// qWarning("PropertyBuffer::intersectedValueChanged");
QString propertyName = property->name();
if (!contains(propertyName))
return;
MultiProperty mp(property);
if (mp == *m_list[propertyName])
{
Property *prop;
QPtrList<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 (QMap<QString, 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, SIGNAL(propertyValueChanged(Property*)), this, SLOT(intersectedValueChanged(Property*)));
}
}
#ifndef PURE_QT
#include "propertylist.moc"
#endif