00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "set.h"
00023 #include "property.h"
00024
00025 #include <qasciidict.h>
00026
00027
00028 #ifdef QT_ONLY
00029
00030 #else
00031 #include <kdebug.h>
00032 #include <klocale.h>
00033 #endif
00034
00035 namespace KoProperty {
00036
00038 static Property Set_nonConstNull;
00039
00041 class SetPrivate
00042 {
00043 public:
00044 SetPrivate() : dict(101, false), readOnly(false) {}
00045 ~SetPrivate(){}
00046
00047
00048 Property::Dict dict;
00049
00050
00051
00052 StringListMap propertiesOfGroup;
00053 QMap<QCString, QString> groupsDescription;
00054
00055 QMap<Property*, QCString> groupForProperty;
00056
00057 bool ownProperty : 1;
00058 bool readOnly : 1;
00059
00060 QCString prevSelection;
00061 QString typeName;
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096 };
00097 }
00098
00099 using namespace KoProperty;
00100
00101
00102 Set::Iterator::Iterator(const Set &set)
00103 {
00104 iterator = new Property::DictIterator(set.d->dict);
00105 }
00106
00107 Set::Iterator::~Iterator()
00108 {
00109 delete iterator;
00110 }
00111
00112 void
00113 Set::Iterator::operator ++()
00114 {
00115 ++(*iterator);
00116 }
00117
00118 Property*
00119 Set::Iterator::operator *()
00120 {
00121 return current();
00122 }
00123
00124 QCString
00125 Set::Iterator::currentKey()
00126 {
00127 if (iterator)
00128 return iterator->currentKey();
00129
00130 return QCString();
00131 }
00132
00133 Property*
00134 Set::Iterator::current()
00135 {
00136 if(iterator)
00137 return iterator->current();
00138
00139 return 0;
00140 }
00141
00143
00144 Set::Set(QObject *parent, const QString &typeName)
00145 : QObject(parent, typeName.latin1())
00146 {
00147 d = new SetPrivate();
00148 d->ownProperty = true;
00149 d->groupsDescription.insert("common", i18n("General properties", "General"));
00150 d->typeName = typeName;
00151 }
00152
00153
00154 Set::Set(const Set &set)
00155 : QObject(0 , set.name())
00156 {
00157 d = new SetPrivate();
00158 *this = set;
00159 }
00160
00161 Set::Set(bool propertyOwner)
00162 : QObject(0, 0)
00163 {
00164 d = new SetPrivate();
00165 d->ownProperty = propertyOwner;
00166 d->groupsDescription.insert("common", i18n("General properties", "General"));
00167 }
00168
00169 Set::~Set()
00170 {
00171 emit aboutToBeCleared();
00172 emit aboutToBeDeleted();
00173 clear();
00174 delete d;
00175 }
00176
00178
00179 void
00180 Set::addPropertyInternal(Property *property, QCString group, bool updateSortingKey)
00181 {
00182 if (group.isEmpty())
00183 group = "common";
00184 if (property == 0) {
00185 kopropertywarn << "Set::addProperty(): property == 0" << endl;
00186 return;
00187 }
00188 if (property->name().isEmpty()) {
00189 kopropertywarn << "Set::addProperty(): COULD NOT ADD NULL PROPERTY" << endl;
00190 return;
00191 }
00192
00193 Property *p = d->dict.find(property->name());
00194 if(p) {
00195 p->addRelatedProperty(property);
00196 }
00197 else {
00198 d->dict.insert(property->name(), property);
00199 addToGroup(group, property);
00200 }
00201
00202 property->addSet(this);
00203 if (updateSortingKey)
00204 property->setSortingKey( d->dict.count() );
00205 }
00206
00207 void
00208 Set::addProperty(Property *property, QCString group)
00209 {
00210 addPropertyInternal(property, group, true);
00211 }
00212
00213 void
00214 Set::removeProperty(Property *property)
00215 {
00216 if(!property)
00217 return;
00218
00219 Property *p = d->dict.take(property->name());
00220 removeFromGroup(p);
00221 if(d->ownProperty) {
00222 emit aboutToDeleteProperty(*this, *p);
00223 delete p;
00224 }
00225 }
00226
00227 void
00228 Set::removeProperty(const QCString &name)
00229 {
00230 if(name.isNull())
00231 return;
00232
00233 Property *p = d->dict.find(name);
00234 removeProperty(p);
00235 }
00236
00237 void
00238 Set::clear()
00239 {
00240 aboutToBeCleared();
00241 d->propertiesOfGroup.clear();
00242 d->groupsDescription.clear();
00243 d->groupForProperty.clear();
00244 Property::DictIterator it(d->dict);
00245 while (it.current())
00246 removeProperty( it.current() );
00247 }
00248
00250
00251 void
00252 Set::addToGroup(const QCString &group, Property *property)
00253 {
00254 if(!property)
00255 return;
00256
00257
00258 if(d->groupForProperty.contains(property) && (d->groupForProperty[property] == group))
00259 return;
00260
00261 if(!d->propertiesOfGroup.contains(group)) {
00262 QValueList<QCString> l;
00263 l.append(property->name());
00264 d->propertiesOfGroup.insert(group, l);
00265 }
00266 else {
00267 d->propertiesOfGroup[group].append(property->name());
00268 }
00269 d->groupForProperty.insert(property, group);
00270 }
00271
00272 void
00273 Set::removeFromGroup(Property *property)
00274 {
00275 if(!property)
00276 return;
00277 QCString group = d->groupForProperty[property];
00278 d->propertiesOfGroup[group].remove(property->name());
00279 if (d->propertiesOfGroup[group].isEmpty()) {
00280
00281 d->propertiesOfGroup.remove(group);
00282 }
00283 d->groupForProperty.remove(property);
00284 }
00285
00286 const StringListMap&
00287 Set::groups()
00288 {
00289 return d->propertiesOfGroup;
00290 }
00291
00292 void
00293 Set::setGroupDescription(const QCString &group, const QString desc)
00294 {
00295 d->groupsDescription[group] = desc;
00296 }
00297
00298 QString
00299 Set::groupDescription(const QCString &group)
00300 {
00301 if(d->groupsDescription.contains(group))
00302 return d->groupsDescription[group];
00303 return group;
00304 }
00305
00307
00308 uint
00309 Set::count() const
00310 {
00311 return d->dict.count();
00312 }
00313
00314 bool
00315 Set::isEmpty() const
00316 {
00317 return d->dict.isEmpty();
00318 }
00319
00320 bool
00321 Set::isReadOnly() const
00322 {
00323 return d->readOnly;
00324 }
00325
00326 void
00327 Set::setReadOnly(bool readOnly)
00328 {
00329 d->readOnly = readOnly;
00330 }
00331
00332 bool
00333 Set::contains(const QCString &name)
00334 {
00335 return d->dict.find(name);
00336 }
00337
00338 Property&
00339 Set::property(const QCString &name)
00340 {
00341 Property *p = d->dict.find(name);
00342 if (p)
00343 return *p;
00344
00345
00346
00347 Set_nonConstNull.setName(0);
00348 kopropertywarn << "Set::property(): PROPERTY \"" << name << "\" NOT FOUND" << endl;
00349 return Set_nonConstNull;
00350 }
00351
00352 Property&
00353 Set::operator[](const QCString &name)
00354 {
00355 return property(name);
00356 }
00357
00358 const Set&
00359 Set::operator= (const Set &set)
00360 {
00361 if(&set == this)
00362 return *this;
00363
00364 clear();
00365
00366 d->ownProperty = set.d->ownProperty;
00367 d->prevSelection = set.d->prevSelection;
00368 d->groupsDescription = set.d->groupsDescription;
00369
00370
00371 for(Property::DictIterator it(set.d->dict); it.current(); ++it) {
00372 Property *prop = new Property( *it.current() );
00373 addPropertyInternal(prop, set.d->groupForProperty[ it.current() ],
00374 false );
00375 }
00376
00377 return *this;
00378 }
00379
00380 void
00381 Set::changeProperty(const QCString &property, const QVariant &value)
00382 {
00383 Property *p = d->dict[property];
00384 if(p)
00385 p->setValue(value);
00386 }
00387
00389
00390 void
00391 Set::debug()
00392 {
00393
00394 if(d->dict.isEmpty()) {
00395 kopropertydbg << "<EMPTY>" << endl;
00396 return;
00397 }
00398 kopropertydbg << d->dict.count() << " properties:" << endl;
00399
00400 for(Property::DictIterator it(d->dict); it.current(); ++it)
00401 it.current()->debug();
00402 }
00403
00404 QCString
00405 Set::prevSelection() const
00406 {
00407 return d->prevSelection;
00408 }
00409
00410 void
00411 Set::setPrevSelection(const QCString &prevSelection)
00412 {
00413 d->prevSelection = prevSelection;
00414 }
00415
00416 QString
00417 Set::typeName() const
00418 {
00419 return d->typeName;
00420 }
00421
00423
00424 Buffer::Buffer()
00425 :Set(false)
00426 {
00427 connect( this, SIGNAL( propertyChanged( KoProperty::Set&, KoProperty::Property& ) ),
00428 this, SLOT(intersectedChanged( KoProperty::Set&, KoProperty::Property& ) ) );
00429
00430 connect( this, SIGNAL( propertyReset( KoProperty::Set&, KoProperty::Property& ) ),
00431 this, SLOT(intersectedReset( KoProperty::Set&, KoProperty::Property& ) ) );
00432 }
00433
00434 Buffer::Buffer(const Set *set)
00435 :Set(false)
00436 {
00437 connect( this, SIGNAL( propertyChanged( KoProperty::Set&, KoProperty::Property& ) ),
00438 this, SLOT(intersectedChanged( KoProperty::Set&, KoProperty::Property& ) ) );
00439
00440 connect( this, SIGNAL( propertyReset( KoProperty::Set&, KoProperty::Property& ) ),
00441 this, SLOT(intersectedReset( KoProperty::Set&, KoProperty::Property& ) ) );
00442
00443 initialSet( set );
00444 }
00445
00446 void Buffer::initialSet(const Set *set)
00447 {
00448
00449 for(Property::DictIterator it(set->d->dict); it.current(); ++it) {
00450 Property *prop = new Property( *it.current() );
00451 QCString group = set->d->groupForProperty[it.current()];
00452 QString groupDesc = set->d->groupsDescription[ group ];
00453 setGroupDescription( group, groupDesc );
00454 addProperty( prop, group );
00455 prop->addRelatedProperty( it.current() );
00456 }
00457 }
00458
00459 void Buffer::intersect(const Set *set)
00460 {
00461 if ( d->dict.isEmpty() )
00462 {
00463 initialSet( set );
00464 return;
00465 }
00466
00467 for(Property::DictIterator it(d->dict); it.current(); ++it) {
00468 const char* key = it.current()->name();
00469 if ( Property *property = set->d->dict[ key ] )
00470 {
00471 blockSignals( true );
00472 it.current()->resetValue();
00473 it.current()->addRelatedProperty( property );
00474 blockSignals( false );
00475 }
00476 else
00477 removeProperty( key );
00478 }
00479 }
00480
00481 void Buffer::intersectedChanged(KoProperty::Set& set, KoProperty::Property& prop)
00482 {
00483 Q_UNUSED(set);
00484 QCString propertyName = prop.name();
00485 if ( !contains( propertyName ) )
00486 return;
00487
00488 const QValueList<Property*> *props = prop.related();
00489 QValueList<Property*>::const_iterator it = props->begin();
00490 for ( ; it != props->end(); ++it ) {
00491 ( *it )->setValue( prop.value(), false );
00492 }
00493 }
00494
00495 void Buffer::intersectedReset(KoProperty::Set& set, KoProperty::Property& prop)
00496 {
00497 Q_UNUSED(set);
00498 QCString propertyName = prop.name();
00499 if ( !contains( propertyName ) )
00500 return;
00501
00502 const QValueList<Property*> *props = prop.related();
00503 QValueList<Property*>::const_iterator it = props->begin();
00504 for ( ; it != props->end(); ++it ) {
00505 ( *it )->setValue( prop.value(), false );
00506 }
00507 }
00508
00509 #include "set.moc"