set.cpp
1/* This file is part of the KDE project
2 Copyright (C) 2004 Cedric Pasteur <cedric.pasteur@free.fr>
3 Copyright (C) 2004 Alexander Dymo <cloudtemple@mskat.net>
4 Copyright (C) 2004-2006 Jaroslaw Staniek <js@iidea.pl>
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
15
16 You should have received a copy of the GNU Library General Public License
17 along with this library; see the file COPYING.LIB. If not, write to
18 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20*/
21
22#include "set.h"
23#include "property.h"
24#include "utils.h"
25
26#include <tqapplication.h>
27#include <tqasciidict.h>
28//#include <tqvaluelist.h>
29
30#include <kdebug.h>
31#include <tdelocale.h>
32
33typedef TQMap<TQCString, TQValueList<TQCString> > StringListMap;
34typedef TQMapIterator<TQCString, TQStringList> StringListMapIterator;
35
36namespace KoProperty {
37
39static Property Set_nonConstNull;
40
42class SetPrivate
43{
44 public:
45 SetPrivate() :
46 dict(101, false),
47 readOnly(false),
48 informAboutClearing(0)
49 {}
50 ~SetPrivate(){}
51
52 //dict of properties in form name: property
53 Property::Dict dict;
54// PropertyList properties;
55 //groups of properties:
56 // list of group name: (list of property names)
57 StringListMap propertiesOfGroup;
58 TQValueList<TQCString> groupNames;
59 TQMap<TQCString, TQString> groupDescriptions;
60 TQMap<TQCString, TQString> groupIcons;
61 // map of property: group
62 TQMap<Property*, TQCString> groupForProperty;
63
64 bool ownProperty : 1;
65 bool readOnly : 1;
66// static Property nonConstNull;
67 TQCString prevSelection;
68 TQString typeName;
69
72 bool* informAboutClearing;
73
74 inline KoProperty::Property& property(const TQCString &name) const
75 {
76 KoProperty::Property *p = dict.find(name);
77 if (p)
78 return *p;
79 Set_nonConstNull.setName(0); //to ensure returned property is null
80 kopropertywarn << "Set::property(): PROPERTY \"" << name << "\" NOT FOUND" << endl;
81 return Set_nonConstNull;
82 }
83};
84
85}
86
87using namespace KoProperty;
88
89//Set::Iterator class
90Set::Iterator::Iterator(const Set &set)
91{
92 iterator = new Property::DictIterator(set.d->dict);
93}
94
95Set::Iterator::~Iterator()
96{
97 delete iterator;
98}
99
100void
101Set::Iterator::operator ++()
102{
103 ++(*iterator);
104}
105
107Set::Iterator::operator *() const
108{
109 return current();
110}
111
112TQCString
113Set::Iterator::currentKey() const
114{
115 if (iterator)
116 return iterator->currentKey();
117
118 return TQCString();
119}
120
122Set::Iterator::current() const
123{
124 if(iterator)
125 return iterator->current();
126
127 return 0;
128}
129
131
132Set::Set(TQObject *parent, const TQString &typeName)
133: TQObject(parent, typeName.latin1())
134{
135 d = new SetPrivate();
136 d->ownProperty = true;
137 d->groupDescriptions.insert("common", i18n("General properties", "General"));
138 d->typeName = typeName;
139}
140
141
142Set::Set(const Set &set)
143 : TQObject(0 /* implicit sharing the parent is dangerous */, set.name())
144{
145 d = new SetPrivate();
146 *this = set;
147}
148
149Set::Set(bool propertyOwner)
150 : TQObject(0, 0)
151{
152 d = new SetPrivate();
153 d->ownProperty = propertyOwner;
154 d->groupDescriptions.insert("common", i18n("General properties", "General"));
155}
156
157Set::~Set()
158{
159 emit aboutToBeCleared();
160 emit aboutToBeDeleted();
161 clear();
162 delete d;
163}
164
166
167void
168Set::addPropertyInternal(Property *property, TQCString group, bool updateSortingKey)
169{
170 if (group.isEmpty())
171 group = "common";
172 if (property == 0) {
173 kopropertywarn << "Set::addProperty(): property == 0" << endl;
174 return;
175 }
176 if (property->name().isEmpty()) {
177 kopropertywarn << "Set::addProperty(): COULD NOT ADD NULL PROPERTY" << endl;
178 return;
179 }
180
181 Property *p = d->dict.find(property->name());
182 if(p) {
184 }
185 else {
186 d->dict.insert(property->name(), property);
187 addToGroup(group, property);
188 }
189
190 property->addSet(this);
191 if (updateSortingKey)
192 property->setSortingKey( d->dict.count() );
193}
194
195void
196Set::addProperty(Property *property, TQCString group)
197{
198 addPropertyInternal(property, group, true);
199}
200
201void
203{
204 if(!property)
205 return;
206
207 Property *p = d->dict.take(property->name());
209 if(d->ownProperty) {
210 emit aboutToDeleteProperty(*this, *p);
211 delete p;
212 }
213}
214
215void
216Set::removeProperty(const TQCString &name)
217{
218 if(name.isNull())
219 return;
220
221 Property *p = d->dict.find(name);
223}
224
225void
227{
228 if (d->informAboutClearing)
229 *d->informAboutClearing = true;
230 d->informAboutClearing = 0;
232 d->propertiesOfGroup.clear();
233 d->groupNames.clear();
234 d->groupForProperty.clear();
235 d->groupDescriptions.clear();
236 d->groupIcons.clear();
237 Property::DictIterator it(d->dict);
238 while (it.current())
239 removeProperty( it.current() );
240}
241
242void
243Set::informAboutClearing(bool& cleared)
244{
245 cleared = false;
246 d->informAboutClearing = &cleared;
247}
248
250
251void
252Set::addToGroup(const TQCString &group, Property *property)
253{
254 if(!property)
255 return;
256
257 //do not add the same property to the group twice
258 if(d->groupForProperty.contains(property) && (d->groupForProperty[property] == group))
259 return;
260
261 if(!d->propertiesOfGroup.contains(group)) { // group doesn't exist
262 TQValueList<TQCString> l;
263 l.append(property->name());
264 d->propertiesOfGroup.insert(group, l);
265 d->groupNames.append(group);
266 }
267 else {
268 d->propertiesOfGroup[group].append(property->name());
269 }
270 d->groupForProperty.insert(property, group);
271}
272
273void
275{
276 if(!property)
277 return;
278 TQCString group = d->groupForProperty[property];
279 d->propertiesOfGroup[group].remove(property->name());
280 if (d->propertiesOfGroup[group].isEmpty()) {
281 //remove group as well
282 d->propertiesOfGroup.remove(group);
283 TQValueListIterator<TQCString> it = d->groupNames.find(group);
284 if (it != d->groupNames.end()) {
285 d->groupNames.remove(it);
286 }
287 }
288 d->groupForProperty.remove(property);
289}
290
291const TQValueList<TQCString>&
293{
294 return d->groupNames;
295}
296
297const TQValueList<TQCString>&
298Set::propertyNamesForGroup(const TQCString &group) const
299{
300 return d->propertiesOfGroup[group];
301}
302
303void
304Set::setGroupDescription(const TQCString &group, const TQString& desc)
305{
306 d->groupDescriptions[group] = desc;
307}
308
309TQString
310Set::groupDescription(const TQCString &group) const
311{
312 if(d->groupDescriptions.contains(group))
313 return d->groupDescriptions[group];
314 return group;
315}
316
317void
318Set::setGroupIcon(const TQCString &group, const TQString& icon)
319{
320 d->groupIcons[group] = icon;
321}
322
323TQString
324Set::groupIcon(const TQCString &group) const
325{
326 return d->groupIcons[group];
327}
328
330
331uint
333{
334 return d->dict.count();
335}
336
337bool
339{
340 return d->dict.isEmpty();
341}
342
343bool
345{
346 return d->readOnly;
347}
348
349void
350Set::setReadOnly(bool readOnly)
351{
352 d->readOnly = readOnly;
353}
354
355bool
356Set::contains(const TQCString &name) const
357{
358 return d->dict.find(name);
359}
360
362Set::property(const TQCString &name) const
363{
364 return d->property(name);
365}
366
368Set::operator[](const TQCString &name) const
369{
370 return d->property(name);
371}
372
373const Set&
375{
376 if(&set == this)
377 return *this;
378
379 clear();
380
381 d->ownProperty = set.d->ownProperty;
382 d->prevSelection = set.d->prevSelection;
383 d->groupDescriptions = set.d->groupDescriptions;
384
385 // Copy all properties in the list
386 for(Property::DictIterator it(set.d->dict); it.current(); ++it) {
387 Property *prop = new Property( *it.current() );
388 addPropertyInternal(prop, set.d->groupForProperty[ it.current() ],
389 false );
390 }
391
392 return *this;
393}
394
395void
396Set::changeProperty(const TQCString &property, const TQVariant &value)
397{
398 Property *p = d->dict[property];
399 if(p)
400 p->setValue(value);
401}
402
404
405void
407{
408 //kopropertydbg << "List: typeName='" << m_typeName << "'" << endl;
409 if(d->dict.isEmpty()) {
410 kopropertydbg << "<EMPTY>" << endl;
411 return;
412 }
413 kopropertydbg << d->dict.count() << " properties:" << endl;
414
415 for(Property::DictIterator it(d->dict); it.current(); ++it)
416 it.current()->debug();
417}
418
419TQCString
421{
422 return d->prevSelection;
423}
424
425void
426Set::setPrevSelection(const TQCString &prevSelection)
427{
428 d->prevSelection = prevSelection;
429}
430
431TQString
433{
434 return d->typeName;
435}
436
438
439Buffer::Buffer()
440 :Set(false)
441{
442 connect( this, TQ_SIGNAL( propertyChanged( KoProperty::Set&, KoProperty::Property& ) ),
443 this, TQ_SLOT(intersectedChanged( KoProperty::Set&, KoProperty::Property& ) ) );
444
445 connect( this, TQ_SIGNAL( propertyReset( KoProperty::Set&, KoProperty::Property& ) ),
446 this, TQ_SLOT(intersectedReset( KoProperty::Set&, KoProperty::Property& ) ) );
447}
448
449Buffer::Buffer(const Set *set)
450 :Set(false)
451{
452 connect( this, TQ_SIGNAL( propertyChanged( KoProperty::Set&, KoProperty::Property& ) ),
453 this, TQ_SLOT(intersectedChanged( KoProperty::Set&, KoProperty::Property& ) ) );
454
455 connect( this, TQ_SIGNAL( propertyReset( KoProperty::Set&, KoProperty::Property& ) ),
456 this, TQ_SLOT(intersectedReset( KoProperty::Set&, KoProperty::Property& ) ) );
457
458 initialSet( set );
459}
460
461void Buffer::initialSet(const Set *set)
462{
463 //deep copy of set
464 for(Property::DictIterator it(set->d->dict); it.current(); ++it) {
465 Property *prop = new Property( *it.current() );
466 TQCString group = set->d->groupForProperty[it.current()];
467 TQString groupDesc = set->d->groupDescriptions[ group ];
468 setGroupDescription( group, groupDesc );
469 addProperty( prop, group );
470 prop->addRelatedProperty( it.current() );
471 }
472}
473
474void Buffer::intersect(const Set *set)
475{
476 if ( d->dict.isEmpty() )
477 {
478 initialSet( set );
479 return;
480 }
481
482 for(Property::DictIterator it(d->dict); it.current(); ++it) {
483 const char* key = it.current()->name();
484 if ( Property *property = set->d->dict[ key ] )
485 {
486 blockSignals( true );
487 it.current()->resetValue();
488 it.current()->addRelatedProperty( property );
489 blockSignals( false );
490 }
491 else
492 removeProperty( key );
493 }
494}
495
496void Buffer::intersectedChanged(KoProperty::Set& set, KoProperty::Property& prop)
497{
498 Q_UNUSED(set);
499 TQCString propertyName = prop.name();
500 if ( !contains( propertyName ) )
501 return;
502
503 const TQValueList<Property*> *props = prop.related();
504 TQValueList<Property*>::const_iterator it = props->begin();
505 for ( ; it != props->end(); ++it ) {
506 ( *it )->setValue( prop.value(), false );
507 }
508}
509
510void Buffer::intersectedReset(KoProperty::Set& set, KoProperty::Property& prop)
511{
512 Q_UNUSED(set);
513 TQCString propertyName = prop.name();
514 if ( !contains( propertyName ) )
515 return;
516
517 const TQValueList<Property*> *props = prop.related();
518 TQValueList<Property*>::const_iterator it = props->begin();
519 for ( ; it != props->end(); ++it ) {
520 ( *it )->setValue( prop.value(), false );
521 }
522}
523
525
526TQMap<TQCString, TQVariant> KoProperty::propertyValues(const Set& set)
527{
528 TQMap<TQCString, TQVariant> result;
529 for (Set::Iterator it(set); it.current(); ++it)
530 result.insert( it.currentKey(), it.current()->value() );
531
532 return result;
533}
534
535#include "set.moc"
virtual void intersect(const Set *set)
Definition set.cpp:474
The base class representing a single property.
Definition property.h:177
TQCString name() const
Definition property.cpp:248
void addRelatedProperty(Property *property)
Definition property.cpp:710
TQVariant value() const
Definition property.cpp:314
void setName(const TQCString &name)
Definition property.cpp:254
void setValue(const TQVariant &value, bool rememberOldValue=true, bool useCustomProperty=true)
Definition property.cpp:331
const TQValueList< Property * > * related() const
Definition property.cpp:704
A class to iterate over a Set. It behaves like a TQDictIterator. To use it:
Definition set.h:52
Lists holding properties in groups.
Definition set.h:41
void setReadOnly(bool readOnly)
Definition set.cpp:350
void addToGroup(const TQCString &group, Property *property)
Definition set.cpp:252
bool isEmpty() const
Definition set.cpp:338
TQString groupDescription(const TQCString &group) const
Definition set.cpp:310
const Set & operator=(const Set &set)
Definition set.cpp:374
uint count() const
Definition set.cpp:332
void removeFromGroup(Property *property)
Definition set.cpp:274
void removeProperty(Property *property)
Definition set.cpp:202
Property & operator[](const TQCString &name) const
Definition set.cpp:368
void propertyChanged(KoProperty::Set &set, KoProperty::Property &property)
Property & property(const TQCString &name) const
Definition set.cpp:362
TQString typeName() const
Definition set.cpp:432
TQCString prevSelection() const
Definition set.cpp:420
void aboutToBeDeleted()
void propertyReset(KoProperty::Set &set, KoProperty::Property &property)
bool isReadOnly() const
Definition set.cpp:344
void setGroupIcon(const TQCString &group, const TQString &icon)
Definition set.cpp:318
void aboutToBeCleared()
virtual void clear()
Definition set.cpp:226
bool contains(const TQCString &name) const
Definition set.cpp:356
void setGroupDescription(const TQCString &group, const TQString &desc)
Definition set.cpp:304
void addProperty(Property *property, TQCString group="common")
Definition set.cpp:196
void changeProperty(const TQCString &property, const TQVariant &value)
Definition set.cpp:396
void addPropertyInternal(Property *property, TQCString group, bool updateSortingKey)
Definition set.cpp:168
void debug()
Definition set.cpp:406
void aboutToDeleteProperty(KoProperty::Set &set, KoProperty::Property &property)
const TQValueList< TQCString > & groupNames() const
Definition set.cpp:292
const TQValueList< TQCString > & propertyNamesForGroup(const TQCString &group) const
Definition set.cpp:298
TQString groupIcon(const TQCString &group) const
Definition set.cpp:324
const char * name(StdAction id)
Namespace for a set of classes implementing generic properties framework.