|
|
|
/* This file is part of the KDE project
|
|
|
|
Copyright (C) 2004 Cedric Pasteur <cedric.pasteur@free.fr>
|
|
|
|
Copyright (C) 2004 Alexander Dymo <cloudtemple@mskat.net>
|
|
|
|
Copyright (C) 2004-2006 Jaroslaw Staniek <js@iidea.pl>
|
|
|
|
|
|
|
|
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 "property.h"
|
|
|
|
#include "customproperty.h"
|
|
|
|
#include "set.h"
|
|
|
|
#include "factory.h"
|
|
|
|
|
|
|
|
#include <kdebug.h>
|
|
|
|
|
|
|
|
#include <tqobject.h>
|
|
|
|
#include <tqptrdict.h>
|
|
|
|
#include <tqasciidict.h>
|
|
|
|
#include <tqguardedptr.h>
|
|
|
|
|
|
|
|
namespace KoProperty {
|
|
|
|
|
|
|
|
QT_STATIC_CONST_IMPL Property Property::null;
|
|
|
|
|
|
|
|
//! @internal
|
|
|
|
class PropertyPrivate
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
PropertyPrivate()
|
|
|
|
: caption(0), listData(0), changed(false), storable(true),
|
|
|
|
readOnly(false), visible(true),
|
|
|
|
autosync(-1), custom(0), useCustomProperty(true),
|
|
|
|
sets(0), parent(0), children(0), relatedProperties(0),
|
|
|
|
sortingKey(0)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void setCaptionForDisplaying(const TQString& captionForDisplaying)
|
|
|
|
{
|
|
|
|
delete caption;
|
|
|
|
if (captionForDisplaying.simplifyWhiteSpace()!=captionForDisplaying)
|
|
|
|
caption = new TQString(captionForDisplaying.simplifyWhiteSpace());
|
|
|
|
else
|
|
|
|
caption = 0;
|
|
|
|
this->captionForDisplaying = captionForDisplaying;
|
|
|
|
}
|
|
|
|
|
|
|
|
~PropertyPrivate()
|
|
|
|
{
|
|
|
|
delete caption;
|
|
|
|
caption = 0;
|
|
|
|
delete listData;
|
|
|
|
delete children;
|
|
|
|
delete relatedProperties;
|
|
|
|
delete custom;
|
|
|
|
delete sets;
|
|
|
|
}
|
|
|
|
|
|
|
|
int type;
|
|
|
|
TQCString name;
|
|
|
|
TQString captionForDisplaying;
|
|
|
|
TQString* caption;
|
|
|
|
TQString description;
|
|
|
|
TQVariant value;
|
|
|
|
TQVariant oldValue;
|
|
|
|
/*! The string-to-value correspondence list of the property.*/
|
|
|
|
Property::ListData* listData;
|
|
|
|
// TQMap<TQString, TQVariant> *valueList;
|
|
|
|
TQString icon;
|
|
|
|
|
|
|
|
bool changed : 1;
|
|
|
|
bool storable : 1;
|
|
|
|
bool readOnly : 1;
|
|
|
|
bool visible : 1;
|
|
|
|
int autosync;
|
|
|
|
TQMap<TQCString, TQVariant> options;
|
|
|
|
|
|
|
|
CustomProperty *custom;
|
|
|
|
//! Flag used to allow CustomProperty to use setValue()
|
|
|
|
bool useCustomProperty;
|
|
|
|
|
|
|
|
//! Used when a single set is assigned for the property
|
|
|
|
TQGuardedPtr<Set> set;
|
|
|
|
//! Used when multiple sets are assigned for the property
|
|
|
|
TQPtrDict< TQGuardedPtr<Set> > *sets;
|
|
|
|
// TQValueList<Set*> sets;
|
|
|
|
|
|
|
|
Property *parent;
|
|
|
|
TQValueList<Property*> *children;
|
|
|
|
//! list of properties with the same name (when intersecting buffers)
|
|
|
|
TQValueList<Property*> *relatedProperties;
|
|
|
|
|
|
|
|
int sortingKey;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
using namespace KoProperty;
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
Property::ListData::ListData(const TQStringList& keys_, const TQStringList& names_)
|
|
|
|
: names(names_)
|
|
|
|
// , fixed(true)
|
|
|
|
{
|
|
|
|
setKeysAsStringList(keys_);
|
|
|
|
}
|
|
|
|
|
|
|
|
Property::ListData::ListData(const TQValueList<TQVariant> keys_, const TQStringList& names_)
|
|
|
|
: keys(keys_), names(names_)
|
|
|
|
// , fixed(true)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
Property::ListData::ListData()
|
|
|
|
// : fixed(true)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
Property::ListData::~ListData()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void Property::ListData::setKeysAsStringList(const TQStringList& list)
|
|
|
|
{
|
|
|
|
keys.clear();
|
|
|
|
for (TQStringList::ConstIterator it = list.constBegin(); it!=list.constEnd(); ++it) {
|
|
|
|
keys.append(*it);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TQStringList Property::ListData::keysAsStringList() const
|
|
|
|
{
|
|
|
|
TQStringList result;
|
|
|
|
for (TQValueList<TQVariant>::ConstIterator it = keys.constBegin(); it!=keys.constEnd(); ++it) {
|
|
|
|
result.append((*it).toString());
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
/*
|
|
|
|
KOPROPERTY_EXPORT TQMap<TQString, TQVariant>
|
|
|
|
KoProperty::createValueListFromStringLists(const TQStringList &keys, const TQStringList &values)
|
|
|
|
{
|
|
|
|
TQMap<TQString, TQVariant> map;
|
|
|
|
if(keys.count() != values.count())
|
|
|
|
return map;
|
|
|
|
|
|
|
|
TQStringList::ConstIterator valueIt = values.begin();
|
|
|
|
TQStringList::ConstIterator endIt = keys.constEnd();
|
|
|
|
for(TQStringList::ConstIterator it = keys.begin(); it != endIt; ++it, ++valueIt)
|
|
|
|
map.insert( *it, *valueIt);
|
|
|
|
|
|
|
|
return map;
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
Property::Property(const TQCString &name, const TQVariant &value,
|
|
|
|
const TQString &caption, const TQString &description,
|
|
|
|
int type, Property* parent)
|
|
|
|
: d( new PropertyPrivate() )
|
|
|
|
{
|
|
|
|
d->name = name;
|
|
|
|
d->setCaptionForDisplaying(caption);
|
|
|
|
d->description = description;
|
|
|
|
|
|
|
|
if(type == Auto)
|
|
|
|
d->type = value.type();
|
|
|
|
else
|
|
|
|
d->type = type;
|
|
|
|
|
|
|
|
d->custom = FactoryManager::self()->createCustomProperty(this);
|
|
|
|
|
|
|
|
if (parent)
|
|
|
|
parent->addChild(this);
|
|
|
|
setValue(value, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
Property::Property(const TQCString &name, const TQStringList &keys, const TQStringList &strings,
|
|
|
|
const TQVariant &value, const TQString &caption, const TQString &description,
|
|
|
|
int type, Property* parent)
|
|
|
|
: d( new PropertyPrivate() )
|
|
|
|
{
|
|
|
|
d->name = name;
|
|
|
|
d->setCaptionForDisplaying(caption);
|
|
|
|
d->description = description;
|
|
|
|
d->type = type;
|
|
|
|
setListData(keys, strings);
|
|
|
|
|
|
|
|
d->custom = FactoryManager::self()->createCustomProperty(this);
|
|
|
|
|
|
|
|
if (parent)
|
|
|
|
parent->addChild(this);
|
|
|
|
setValue(value, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
Property::Property(const TQCString &name, ListData* listData,
|
|
|
|
const TQVariant &value, const TQString &caption, const TQString &description,
|
|
|
|
int type, Property* parent)
|
|
|
|
: d( new PropertyPrivate() )
|
|
|
|
{
|
|
|
|
d->name = name;
|
|
|
|
d->setCaptionForDisplaying(caption);
|
|
|
|
d->description = description;
|
|
|
|
d->type = type;
|
|
|
|
d->listData = listData;
|
|
|
|
|
|
|
|
d->custom = FactoryManager::self()->createCustomProperty(this);
|
|
|
|
|
|
|
|
if (parent)
|
|
|
|
parent->addChild(this);
|
|
|
|
setValue(value, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
Property::Property()
|
|
|
|
: d( new PropertyPrivate() )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
Property::Property(const Property &prop)
|
|
|
|
: d( new PropertyPrivate() )
|
|
|
|
{
|
|
|
|
*this = prop;
|
|
|
|
}
|
|
|
|
|
|
|
|
Property::~Property()
|
|
|
|
{
|
|
|
|
delete d;
|
|
|
|
d = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQCString
|
|
|
|
Property::name() const
|
|
|
|
{
|
|
|
|
return d->name;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Property::setName(const TQCString &name)
|
|
|
|
{
|
|
|
|
d->name = name;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString
|
|
|
|
Property::caption() const
|
|
|
|
{
|
|
|
|
return d->caption ? *d->caption : d->captionForDisplaying;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString
|
|
|
|
Property::captionForDisplaying() const
|
|
|
|
{
|
|
|
|
return d->captionForDisplaying;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Property::setCaption(const TQString &caption)
|
|
|
|
{
|
|
|
|
d->setCaptionForDisplaying(caption);
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString
|
|
|
|
Property::description() const
|
|
|
|
{
|
|
|
|
return d->description;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Property::setDescription(const TQString &desc)
|
|
|
|
{
|
|
|
|
d->description = desc;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
Property::type() const
|
|
|
|
{
|
|
|
|
return d->type;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Property::setType(int type)
|
|
|
|
{
|
|
|
|
d->type = type;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString
|
|
|
|
Property::icon() const
|
|
|
|
{
|
|
|
|
return d->icon;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Property::setIcon(const TQString &icon)
|
|
|
|
{
|
|
|
|
d->icon = icon;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQVariant
|
|
|
|
Property::value() const
|
|
|
|
{
|
|
|
|
if(d->custom && d->custom->handleValue())
|
|
|
|
return d->custom->value();
|
|
|
|
return d->value;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQVariant
|
|
|
|
Property::oldValue() const
|
|
|
|
{
|
|
|
|
/* if(d->oldValue.isNull())
|
|
|
|
return value();
|
|
|
|
else*/
|
|
|
|
return d->oldValue;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Property::setValue(const TQVariant &value, bool rememberOldValue, bool useCustomProperty)
|
|
|
|
{
|
|
|
|
if (d->name.isEmpty()) {
|
|
|
|
kopropertywarn << "Property::setValue(): COULD NOT SET value to a null property" << endl;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
TQVariant currentValue = this->value();
|
|
|
|
const TQVariant::Type t = currentValue.type();
|
|
|
|
const TQVariant::Type newt = value.type();
|
|
|
|
// kopropertydbg << d->name << " : setValue('" << value.toString() << "' type=" << type() << ")" << endl;
|
|
|
|
if (t != newt && !currentValue.isNull() && !value.isNull()
|
|
|
|
&& !( (t==TQVariant::Int && newt==TQVariant::UInt)
|
|
|
|
|| (t==TQVariant::UInt && newt==TQVariant::Int)
|
|
|
|
|| (t==TQVariant::CString && newt==TQVariant::String)
|
|
|
|
|| (t==TQVariant::String && newt==TQVariant::CString)
|
|
|
|
|| (t==TQVariant::ULongLong && newt==TQVariant::LongLong)
|
|
|
|
|| (t==TQVariant::LongLong && newt==TQVariant::ULongLong)
|
|
|
|
)) {
|
|
|
|
kopropertywarn << "Property::setValue(): INCOMPATIBLE TYPES! old=" << currentValue
|
|
|
|
<< " new=" << value << endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
//1. Check if the value should be changed
|
|
|
|
bool ch;
|
|
|
|
if (t == TQVariant::DateTime
|
|
|
|
|| t == TQVariant::Time) {
|
|
|
|
//for date and datetime types: compare with strings, because there
|
|
|
|
//can be miliseconds difference
|
|
|
|
ch = (currentValue.toString() != value.toString());
|
|
|
|
}
|
|
|
|
else if (t == TQVariant::String || t==TQVariant::CString) {
|
|
|
|
//property is changed for string type,
|
|
|
|
//if one of value is empty and other isn't..
|
|
|
|
ch = ( (currentValue.toString().isEmpty() != value.toString().isEmpty())
|
|
|
|
//..or both are not empty and values differ
|
|
|
|
|| (!currentValue.toString().isEmpty() && !value.toString().isEmpty() && currentValue != value) );
|
|
|
|
}
|
|
|
|
else if (t == TQVariant::Invalid && newt == TQVariant::Invalid)
|
|
|
|
ch = false;
|
|
|
|
else
|
|
|
|
ch = (currentValue != value);
|
|
|
|
|
|
|
|
if (!ch)
|
|
|
|
return;
|
|
|
|
|
|
|
|
//2. Then change it, and store old value if necessary
|
|
|
|
if(rememberOldValue) {
|
|
|
|
if(!d->changed)
|
|
|
|
d->oldValue = currentValue;
|
|
|
|
d->changed = true;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
d->oldValue = TQVariant(); // clear old value
|
|
|
|
d->changed = false;
|
|
|
|
}
|
|
|
|
TQVariant prevValue;
|
|
|
|
if(d->custom && useCustomProperty) {
|
|
|
|
d->custom->setValue(value, rememberOldValue);
|
|
|
|
prevValue = d->custom->value();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
prevValue = currentValue;
|
|
|
|
|
|
|
|
if (!d->custom || !useCustomProperty || !d->custom->handleValue())
|
|
|
|
d->value = value;
|
|
|
|
|
|
|
|
emitPropertyChanged(); // called as last step in this method!
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Property::resetValue()
|
|
|
|
{
|
|
|
|
d->changed = false;
|
|
|
|
bool cleared = false;
|
|
|
|
if (d->set)
|
|
|
|
d->set->informAboutClearing(cleared); //inform me about possibly clearing the property sets
|
|
|
|
setValue(oldValue(), false);
|
|
|
|
if (cleared)
|
|
|
|
return; //property set has been cleared: no further actions make sense as 'this' is dead
|
|
|
|
|
|
|
|
// maybe parent prop is also unchanged now
|
|
|
|
if(d->parent && d->parent->value() == d->parent->oldValue())
|
|
|
|
d->parent->d->changed = false;
|
|
|
|
|
|
|
|
if (d->sets) {
|
|
|
|
for (TQPtrDictIterator< TQGuardedPtr<Set> > it(*d->sets); it.current(); ++it) {
|
|
|
|
if (it.current()) //may be destroyed in the meantime
|
|
|
|
emit (*it.current())->propertyReset(**it.current(), *this);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (d->set) {
|
|
|
|
emit d->set->propertyReset(*d->set, *this);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//const TQMap<TQString, TQVariant>*
|
|
|
|
Property::ListData*
|
|
|
|
Property::listData() const
|
|
|
|
{
|
|
|
|
return d->listData;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Property::setListData(ListData* list) //const TQMap<TQString, TQVariant> &list)
|
|
|
|
{
|
|
|
|
// if(!d->valueList)
|
|
|
|
// d->valueList = new TQMap<TQString, TQVariant>();
|
|
|
|
if (list == d->listData)
|
|
|
|
return;
|
|
|
|
delete d->listData;
|
|
|
|
d->listData = list;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Property::setListData(const TQStringList &keys, const TQStringList &names)
|
|
|
|
{
|
|
|
|
ListData* list = new ListData(keys, names);
|
|
|
|
setListData(list);
|
|
|
|
|
|
|
|
// if(!d->valueList)
|
|
|
|
// d->valueList = new TQMap<TQString, TQVariant>();
|
|
|
|
// *(d->valueList) = createValueListFromStringLists(keys, values);
|
|
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
bool
|
|
|
|
Property::isNull() const
|
|
|
|
{
|
|
|
|
return d->name.isEmpty();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
Property::isModified() const
|
|
|
|
{
|
|
|
|
return d->changed;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Property::clearModifiedFlag()
|
|
|
|
{
|
|
|
|
d->changed = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
Property::isReadOnly() const
|
|
|
|
{
|
|
|
|
return d->readOnly;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Property::setReadOnly(bool readOnly)
|
|
|
|
{
|
|
|
|
d->readOnly = readOnly;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
Property::isVisible() const
|
|
|
|
{
|
|
|
|
return d->visible;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Property::setVisible(bool visible)
|
|
|
|
{
|
|
|
|
d->visible = visible;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
Property::autoSync() const
|
|
|
|
{
|
|
|
|
return d->autosync;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Property::setAutoSync(int sync)
|
|
|
|
{
|
|
|
|
d->autosync = sync;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
Property::isStorable() const
|
|
|
|
{
|
|
|
|
return d->storable;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Property::setStorable(bool storable)
|
|
|
|
{
|
|
|
|
d->storable = storable;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Property::setOption(const char* name, const TQVariant& val)
|
|
|
|
{
|
|
|
|
d->options[name] = val;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQVariant
|
|
|
|
Property::option(const char* name) const
|
|
|
|
{
|
|
|
|
if (d->options.contains(name))
|
|
|
|
return d->options[name];
|
|
|
|
return TQVariant();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
Property::hasOptions() const
|
|
|
|
{
|
|
|
|
return !d->options.isEmpty();
|
|
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
Property::operator bool () const
|
|
|
|
{
|
|
|
|
return !isNull();
|
|
|
|
}
|
|
|
|
|
|
|
|
const Property&
|
|
|
|
Property::operator= (const TQVariant& val)
|
|
|
|
{
|
|
|
|
setValue(val);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
const Property&
|
|
|
|
Property::operator= (const Property &property)
|
|
|
|
{
|
|
|
|
if(&property == this)
|
|
|
|
return *this;
|
|
|
|
|
|
|
|
if(d->listData) {
|
|
|
|
delete d->listData;
|
|
|
|
d->listData = 0;
|
|
|
|
}
|
|
|
|
if(d->children) {
|
|
|
|
delete d->children;
|
|
|
|
d->children = 0;
|
|
|
|
}
|
|
|
|
if(d->relatedProperties) {
|
|
|
|
delete d->relatedProperties;
|
|
|
|
d->relatedProperties = 0;
|
|
|
|
}
|
|
|
|
if(d->custom) {
|
|
|
|
delete d->custom;
|
|
|
|
d->custom = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
d->name = property.d->name;
|
|
|
|
d->setCaptionForDisplaying(property.captionForDisplaying());
|
|
|
|
d->description = property.d->description;
|
|
|
|
d->type = property.d->type;
|
|
|
|
|
|
|
|
d->icon = property.d->icon;
|
|
|
|
d->autosync = property.d->autosync;
|
|
|
|
d->visible = property.d->visible;
|
|
|
|
d->storable = property.d->storable;
|
|
|
|
d->readOnly = property.d->readOnly;
|
|
|
|
d->options = property.d->options;
|
|
|
|
|
|
|
|
if(property.d->listData) {
|
|
|
|
d->listData = new ListData(*property.d->listData); //TQMap<TQString, TQVariant>(*(property.d->valueList));
|
|
|
|
}
|
|
|
|
if(property.d->custom) {
|
|
|
|
d->custom = FactoryManager::self()->createCustomProperty(this);
|
|
|
|
// updates all children value, using CustomProperty
|
|
|
|
setValue(property.value());
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
d->value = property.d->value;
|
|
|
|
if(property.d->children) {
|
|
|
|
// no CustomProperty (should never happen), simply copy all children
|
|
|
|
d->children = new TQValueList<Property*>();
|
|
|
|
TQValueList<Property*>::ConstIterator endIt = property.d->children->constEnd();
|
|
|
|
for(TQValueList<Property*>::ConstIterator it = property.d->children->constBegin(); it != endIt; ++it) {
|
|
|
|
Property *child = new Property( *(*it) );
|
|
|
|
addChild(child);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(property.d->relatedProperties) {
|
|
|
|
d->relatedProperties = new TQValueList<Property*>( *(property.d->relatedProperties));
|
|
|
|
}
|
|
|
|
|
|
|
|
// update these later because they may have been changed when creating children
|
|
|
|
d->oldValue = property.d->oldValue;
|
|
|
|
d->changed = property.d->changed;
|
|
|
|
d->sortingKey = property.d->sortingKey;
|
|
|
|
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
Property::operator ==(const Property &prop) const
|
|
|
|
{
|
|
|
|
return ((d->name == prop.d->name) && (value() == prop.value()));
|
|
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
const TQValueList<Property*>*
|
|
|
|
Property::children() const
|
|
|
|
{
|
|
|
|
return d->children;
|
|
|
|
}
|
|
|
|
|
|
|
|
Property*
|
|
|
|
Property::child(const TQCString &name)
|
|
|
|
{
|
|
|
|
TQValueList<Property*>::ConstIterator endIt = d->children->constEnd();
|
|
|
|
for(TQValueList<Property*>::ConstIterator it = d->children->constBegin(); it != endIt; ++it) {
|
|
|
|
if((*it)->name() == name)
|
|
|
|
return *it;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
Property*
|
|
|
|
Property::parent() const
|
|
|
|
{
|
|
|
|
return d->parent;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Property::addChild(Property *prop)
|
|
|
|
{
|
|
|
|
if (!prop)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if(!d->children || tqFind( d->children->begin(), d->children->end(), prop) == d->children->end()) { // not in our list
|
|
|
|
if(!d->children)
|
|
|
|
d->children = new TQValueList<Property*>();
|
|
|
|
d->children->append(prop);
|
|
|
|
prop->setSortingKey(d->children->count());
|
|
|
|
prop->d->parent = this;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
kopropertywarn << "Property::addChild(): property \"" << name()
|
|
|
|
<< "\": child property \"" << prop->name() << "\" already added" << endl;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Property::addSet(Set *set)
|
|
|
|
{
|
|
|
|
if (!set)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (!d->set) {//simple case
|
|
|
|
d->set = set;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if ((Set*)d->set==set)
|
|
|
|
return;
|
|
|
|
TQGuardedPtr<Set> *pset = d->sets ? d->sets->find(set) : 0;
|
|
|
|
if (pset && (Set*)*pset == set)
|
|
|
|
return;
|
|
|
|
if (!d->sets) {
|
|
|
|
d->sets = new TQPtrDict< TQGuardedPtr<Set> >( 101 );
|
|
|
|
d->sets->setAutoDelete(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
d->sets->replace(set, new TQGuardedPtr<Set>( set ));
|
|
|
|
|
|
|
|
// TQValueList<Set*>::iterator it = tqFind( d->sets.begin(), d->sets.end(), set);
|
|
|
|
// if(it == d->sets.end()) // not in our list
|
|
|
|
// d->sets.append(set);
|
|
|
|
}
|
|
|
|
|
|
|
|
const TQValueList<Property*>*
|
|
|
|
Property::related() const
|
|
|
|
{
|
|
|
|
return d->relatedProperties;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Property::addRelatedProperty(Property *property)
|
|
|
|
{
|
|
|
|
if(!d->relatedProperties)
|
|
|
|
d->relatedProperties = new TQValueList<Property*>();
|
|
|
|
|
|
|
|
TQValueList<Property*>::iterator it = tqFind( d->relatedProperties->begin(), d->relatedProperties->end(), property);
|
|
|
|
if(it == d->relatedProperties->end()) // not in our list
|
|
|
|
d->relatedProperties->append(property);
|
|
|
|
}
|
|
|
|
|
|
|
|
CustomProperty*
|
|
|
|
Property::customProperty() const
|
|
|
|
{
|
|
|
|
return d->custom;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Property::setCustomProperty(CustomProperty *prop)
|
|
|
|
{
|
|
|
|
d->custom = prop;
|
|
|
|
}
|
|
|
|
|
|
|
|
int Property::sortingKey() const
|
|
|
|
{
|
|
|
|
return d->sortingKey;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Property::setSortingKey(int key)
|
|
|
|
{
|
|
|
|
d->sortingKey = key;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Property::emitPropertyChanged()
|
|
|
|
{
|
|
|
|
if (d->sets) {
|
|
|
|
for (TQPtrDictIterator< TQGuardedPtr<Set> > it(*d->sets); it.current(); ++it) {
|
|
|
|
if (it.current()) {//may be destroyed in the meantime
|
|
|
|
emit (*it.current())->propertyChangedInternal(**it.current(), *this);
|
|
|
|
emit (*it.current())->propertyChanged(**it.current(), *this);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (d->set) {
|
|
|
|
//if the slot connect with that signal may call set->clear() - that's
|
|
|
|
//the case e.g. at kexi/plugins/{macros|scripting}/* - this Property
|
|
|
|
//may got destroyed ( see Set::removeProperty(Property*) ) while we are
|
|
|
|
//still on it. So, if we try to access ourself/this once the signal
|
|
|
|
//got emitted we may end in a very hard to reproduce crash. So, the
|
|
|
|
//emit should happen as last step in this method!
|
|
|
|
emit d->set->propertyChangedInternal(*d->set, *this);
|
|
|
|
emit d->set->propertyChanged(*d->set, *this);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
void
|
|
|
|
Property::debug()
|
|
|
|
{
|
|
|
|
TQString dbg = "Property( name='" + TQString(d->name) + "' desc='" + d->description
|
|
|
|
+ "' val=" + (value().isValid() ? value().toString() : "<INVALID>");
|
|
|
|
if (!d->oldValue.isValid())
|
|
|
|
dbg += (", oldVal='" + d->oldValue.toString() + '\'');
|
|
|
|
dbg += (TQString(d->changed ? " " : " un") + "changed");
|
|
|
|
dbg += (d->visible ? " visible" : " hidden");
|
|
|
|
dbg+=" )";
|
|
|
|
|
|
|
|
kopropertydbg << dbg << endl;
|
|
|
|
}
|