lib

set.cpp

00001 /* This file is part of the KDE project
00002    Copyright (C) 2004 Cedric Pasteur <cedric.pasteur@free.fr>
00003    Copyright (C) 2004 Alexander Dymo <cloudtemple@mskat.net>
00004    Copyright (C) 2004-2006 Jaroslaw Staniek <js@iidea.pl>
00005 
00006    This library is free software; you can redistribute it and/or
00007    modify it under the terms of the GNU Library General Public
00008    License as published by the Free Software Foundation; either
00009    version 2 of the License, or (at your option) any later version.
00010 
00011    This library is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014    Library General Public License for more details.
00015 
00016    You should have received a copy of the GNU Library General Public License
00017    along with this library; see the file COPYING.LIB.  If not, write to
00018    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00019  * Boston, MA 02110-1301, USA.
00020 */
00021 
00022 #include "set.h"
00023 #include "property.h"
00024 
00025 #include <qasciidict.h>
00026 //#include <qvaluelist.h>
00027 
00028 #ifdef QT_ONLY
00029 // \todo
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     //dict of properties in form name: property
00048     Property::Dict dict;
00049 //  PropertyList properties;
00050     //groups of properties:
00051     // list of group name: (list of property names)
00052     StringListMap propertiesOfGroup;
00053     QMap<QCString, QString>  groupsDescription;
00054     // map of property: group
00055     QMap<Property*, QCString> groupForProperty;
00056 
00057     bool ownProperty : 1;
00058     bool readOnly : 1;
00059 //  static Property nonConstNull;
00060     QCString prevSelection;
00061     QString typeName;
00062 /*
00063     bool contains(const QCString &name)
00064     {
00065         PropertyList::iterator it = properties.begin();
00066         for( ; it != properties.end(); ++it )
00067             if ( ( *it )->name() == name )
00068                 return true;
00069 
00070         return false;
00071     }
00072 
00073     Property* operator[](const QCString &name)
00074     {
00075         PropertyList::iterator it = properties.begin();
00076         for( ; it != properties.end(); ++it )
00077             if ( ( *it )->name() == name )
00078                 return ( *it );
00079 
00080         return 0L;
00081     }
00082 
00083     Property* take(const QCString &name)
00084     {
00085         Property *p = 0L;
00086         PropertyList::iterator it = properties.begin();
00087         for( ; it != properties.end(); ++it )
00088             if ( ( *it )->name() == name )
00089             {
00090                 p = ( *it );
00091                 properties.remove( it );
00092             }
00093         return p;
00094     }
00095 */
00096 };
00097 }
00098 
00099 using namespace KoProperty;
00100 
00101 //Set::Iterator class
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 /* implicit sharing the parent is dangerous */, 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     //do not add the same property to the group twice
00258     if(d->groupForProperty.contains(property) && (d->groupForProperty[property] == group))
00259         return;
00260 
00261     if(!d->propertiesOfGroup.contains(group)) { // group doesn't exist
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         //remove group as well
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 //      p = new Property();
00345 //      //addProperty(p); // maybe just return a null property
00346 //  }
00347     Set_nonConstNull.setName(0); //to ensure returned property is null
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     // Copy all properties in the list
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     //kopropertydbg << "List: typeName='" << m_typeName << "'" << endl;
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     //deep copy of set
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"
KDE Home | KDE Accessibility Home | Description of Access Keys