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 }
00110 
00111 void
00112 Set::Iterator::operator ++()
00113 {
00114     ++(*iterator);
00115 }
00116 
00117 Property*
00118 Set::Iterator::operator *()
00119 {
00120     return current();
00121 }
00122 
00123 QCString
00124 Set::Iterator::currentKey()
00125 {
00126     if (iterator)
00127         return iterator->currentKey();
00128 
00129     return QCString();
00130 }
00131 
00132 Property*
00133 Set::Iterator::current()
00134 {
00135     if(iterator)
00136         return iterator->current();
00137 
00138     return 0;
00139 }
00140 
00142 
00143 Set::Set(QObject *parent, const QString &typeName)
00144 : QObject(parent, typeName.latin1())
00145 {
00146     d = new SetPrivate();
00147     d->ownProperty = true;
00148     d->groupsDescription.insert("common", i18n("General properties", "General"));
00149     d->typeName = typeName;
00150 }
00151 
00152 
00153 Set::Set(const Set &l)
00154  : QObject(l.parent(), l.name())
00155 {
00156     d = new SetPrivate();
00157     *this = l;
00158 }
00159 
00160 Set::Set(bool propertyOwner)
00161  : QObject(0, 0)
00162 {
00163     d = new SetPrivate();
00164     d->ownProperty = propertyOwner;
00165     d->groupsDescription.insert("common", i18n("General properties", "General"));
00166 }
00167 
00168 Set::~Set()
00169 {
00170     emit aboutToBeCleared();
00171     emit aboutToBeDeleted();
00172     clear();
00173     delete d;
00174 }
00175 
00177 
00178 void
00179 Set::addProperty(Property *property, QCString group)
00180 {
00181     if (group.isEmpty())
00182         group = "common";
00183     if (property == 0) {
00184         kopropertywarn << "Set::addProperty(): property == 0" << endl; 
00185         return;
00186     }
00187     if (property->name().isEmpty()) {
00188         kopropertywarn << "Set::addProperty(): COULD NOT ADD NULL PROPERTY" << endl; 
00189         return;
00190     }
00191 
00192     if(d->dict.find(property->name())) {
00193         Property *p = d->dict[property->name()];
00194         p->addRelatedProperty(property);
00195     }
00196     else {
00197         d->dict.insert(property->name(), property);
00198         addToGroup(group, property);
00199     }
00200 
00201     property->addSet(this);
00202     property->setSortingKey( d->dict.count() );
00203 }
00204 
00205 void
00206 Set::removeProperty(Property *property)
00207 {
00208     if(!property)
00209         return;
00210 
00211     Property *p = d->dict.take(property->name());
00212     removeFromGroup(p);
00213     if(d->ownProperty) {
00214         emit aboutToDeleteProperty(*this, *p);
00215         delete p;
00216     }
00217 }
00218 
00219 void
00220 Set::removeProperty(const QCString &name)
00221 {
00222     if(name.isNull())
00223         return;
00224 
00225     Property *p = d->dict.take(name);
00226     removeProperty(p);
00227 }
00228 
00229 void
00230 Set::clear()
00231 {
00232     aboutToBeCleared();
00233     Property::DictIterator it(d->dict);
00234     while (it.current())
00235         removeProperty( it.current() );
00236 }
00237 
00239 
00240 void
00241 Set::addToGroup(const QCString &group, Property *property)
00242 {
00243     if(!property)
00244         return;
00245 
00246     //do not add same property to the group twice
00247     if(d->groupForProperty.contains(property) && (d->groupForProperty[property] == group))
00248         return;
00249 
00250     if(!d->propertiesOfGroup.contains(group)) { // group doesn't exist
00251         QValueList<QCString> l;
00252         l.append(property->name());
00253         d->propertiesOfGroup.insert(group, l);
00254     }
00255     else {
00256         d->propertiesOfGroup[group].append(property->name());
00257     }
00258     d->groupForProperty.insert(property, group);
00259 }
00260 
00261 void
00262 Set::removeFromGroup(Property *property)
00263 {
00264     if(!property)
00265         return;
00266     QCString group = d->groupForProperty[property];
00267     d->propertiesOfGroup[group].remove(property->name());
00268     d->groupForProperty.remove(property);
00269 }
00270 
00271 const StringListMap&
00272 Set::groups()
00273 {
00274     return d->propertiesOfGroup;
00275 }
00276 
00277 void
00278 Set::setGroupDescription(const QCString &group, const QString desc)
00279 {
00280     d->groupsDescription[group] = desc;
00281 }
00282 
00283 QString
00284 Set::groupDescription(const QCString &group)
00285 {
00286     if(d->groupsDescription.contains(group))
00287         return d->groupsDescription[group];
00288     return group;
00289 }
00290 
00292 
00293 uint
00294 Set::count() const
00295 {
00296     return d->dict.count();
00297 }
00298 
00299 bool
00300 Set::isEmpty() const
00301 {
00302     return d->dict.isEmpty();
00303 }
00304 
00305 bool
00306 Set::isReadOnly() const
00307 {
00308     return d->readOnly;
00309 }
00310 
00311 void
00312 Set::setReadOnly(bool readOnly)
00313 {
00314     d->readOnly = readOnly;
00315 }
00316 
00317 bool
00318 Set::contains(const QCString &name)
00319 {
00320     return d->dict.find(name);
00321 }
00322 
00323 Property&
00324 Set::property(const QCString &name)
00325 {
00326     Property *p = d->dict[name];
00327     if (p)
00328         return *p;
00329 //      p = new Property();
00330 //      //addProperty(p); // maybe just return a null property
00331 //  }
00332     Set_nonConstNull.setName(0); //to ensure returned property is null
00333     kopropertywarn << "Set::property(): PROPERTY \"" << name << "\" NOT FOUND" << endl;
00334     return Set_nonConstNull;
00335 }
00336 
00337 Property&
00338 Set::operator[](const QCString &name)
00339 {
00340     return property(name);
00341 }
00342 
00343 const Set&
00344 Set::operator= (const Set &l)
00345 {
00346     if(&l == this)
00347         return *this;
00348 
00349     d->dict.clear();
00350     d->groupForProperty.clear();
00351 
00352     d->ownProperty = l.d->ownProperty;
00353     d->prevSelection = l.d->prevSelection;
00354     d->groupsDescription = l.d->groupsDescription;
00355     d->propertiesOfGroup = l.d->propertiesOfGroup;
00356 
00357     // Copy all properties in the list
00358     for(Property::DictIterator it(l.d->dict); it.current(); ++it) {
00359         Property *prop = new Property( *it.current() );
00360         addProperty(prop, l.d->groupForProperty[ it.current() ] );
00361     }
00362 
00363     return *this;
00364 }
00365 
00366 void
00367 Set::changeProperty(const QCString &property, const QVariant &value)
00368 {
00369     Property *p = d->dict[property];
00370     if(p)
00371         p->setValue(value);
00372 }
00373 
00375 
00376 void
00377 Set::debug()
00378 {
00379     //kopropertydbg << "List: typeName='" << m_typeName << "'" << endl;
00380     if(d->dict.isEmpty()) {
00381         kopropertydbg << "<EMPTY>" << endl;
00382         return;
00383     }
00384     kopropertydbg << d->dict.count() << " properties:" << endl;
00385 
00386     for(Property::DictIterator it(d->dict); it.current(); ++it)
00387         it.current()->debug();
00388 }
00389 
00390 QCString
00391 Set::prevSelection() const
00392 {
00393     return d->prevSelection;
00394 }
00395 
00396 void
00397 Set::setPrevSelection(const QCString &prevSelection)
00398 {
00399     d->prevSelection = prevSelection;
00400 }
00401 
00402 QString
00403 Set::typeName() const
00404 {
00405     return d->typeName;
00406 }
00407 
00409 
00410 Buffer::Buffer()
00411     :Set(false)
00412 {
00413     connect( this, SIGNAL( propertyChanged( KoProperty::Set&, KoProperty::Property& ) ),
00414              this, SLOT(intersectedChanged( KoProperty::Set&, KoProperty::Property& ) ) );
00415 
00416     connect( this, SIGNAL( propertyReset( KoProperty::Set&, KoProperty::Property& ) ),
00417              this, SLOT(intersectedReset( KoProperty::Set&, KoProperty::Property& ) ) );
00418 }
00419 
00420 Buffer::Buffer(const Set *set)
00421     :Set(false)
00422 {
00423     connect( this, SIGNAL( propertyChanged( KoProperty::Set&, KoProperty::Property& ) ),
00424              this, SLOT(intersectedChanged( KoProperty::Set&, KoProperty::Property& ) ) );
00425 
00426     connect( this, SIGNAL( propertyReset( KoProperty::Set&, KoProperty::Property& ) ),
00427              this, SLOT(intersectedReset( KoProperty::Set&, KoProperty::Property& ) ) );
00428 
00429     initialSet( set );
00430 }
00431 
00432 void Buffer::initialSet(const Set *set)
00433 {
00434     //deep copy of set
00435     for(Property::DictIterator it(set->d->dict); it.current(); ++it) {
00436         Property *prop = new Property( *it.current() );
00437         QCString group = set->d->groupForProperty[it.current()];
00438         QString groupDesc = set->d->groupsDescription[ group ];
00439         setGroupDescription( group, groupDesc );
00440         addProperty( prop, group );
00441         prop->addRelatedProperty( it.current() );
00442     }
00443 }
00444 
00445 void Buffer::intersect(const Set *set)
00446 {
00447     if ( d->dict.isEmpty() )
00448     {
00449         initialSet( set );
00450         return;
00451     }
00452 
00453      for(Property::DictIterator it(d->dict); it.current(); ++it) {
00454         const char* key = it.current()->name();
00455         if ( Property *property =  set->d->dict[ key ] )
00456         {
00457                 blockSignals( true );
00458                 it.current()->resetValue();
00459                 it.current()->addRelatedProperty( property );
00460                 blockSignals( false );
00461         }
00462         else
00463             removeProperty( key );
00464     }
00465 }
00466 
00467 void Buffer::intersectedChanged(KoProperty::Set& set, KoProperty::Property& prop)
00468 {
00469     Q_UNUSED(set);
00470     QCString propertyName = prop.name();
00471     if ( !contains( propertyName ) )
00472         return;
00473 
00474     const QValueList<Property*> *props = prop.related();
00475     QValueList<Property*>::const_iterator it = props->begin();
00476     for ( ; it != props->end(); ++it ) {
00477         ( *it )->setValue( prop.value(), false );
00478     }
00479 }
00480 
00481 void Buffer::intersectedReset(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 #include "set.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys