kexi

widgetpropertyset.cpp

00001 /* This file is part of the KDE project
00002    Copyright (C) 2004 Cedric Pasteur <cedric.pasteur@free.fr>
00003    Copyright (C) 2004-2006 Jaroslaw Staniek <js@iidea.pl>
00004 
00005    This library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Library General Public
00007    License as published by the Free Software Foundation; either
00008    version 2 of the License, or (at your option) any later version.
00009 
00010    This library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Library General Public License for more details.
00014 
00015    You should have received a copy of the GNU Library General Public License
00016    along with this library; see the file COPYING.LIB.  If not, write to
00017    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018  * Boston, MA 02110-1301, USA.
00019 */
00020 #include "widgetpropertyset.h"
00021 
00022 #include <qstringlist.h>
00023 #include <qstrlist.h>
00024 #include <qmetaobject.h>
00025 #include <qvariant.h>
00026 #include <qevent.h>
00027 #include <qlayout.h>
00028 #include <qapplication.h>
00029 #include <qeventloop.h>
00030 
00031 #include <klocale.h>
00032 #include <kdebug.h>
00033 #include <kmessagebox.h>
00034 
00035 #include "objecttree.h"
00036 #include "form.h"
00037 #include "container.h"
00038 #include "formmanager.h"
00039 #include "widgetlibrary.h"
00040 #include "commands.h"
00041 #include "widgetwithsubpropertiesinterface.h"
00042 
00043 #include <kexiutils/utils.h>
00044 #include <kexiutils/identifier.h>
00045 
00046 using namespace KFormDesigner;
00047 
00048 namespace KFormDesigner {
00049 
00051 typedef QValueList< QGuardedPtr<QWidget> > QGuardedWidgetList;
00052 
00054 class WidgetPropertySetPrivate
00055 {
00056     public:
00057         WidgetPropertySetPrivate()
00058         : lastCommand(0), lastGeoCommand(0),
00059          isUndoing(false), slotPropertyChangedEnabled(true),
00060          slotPropertyChanged_addCommandEnabled(true),
00061          origActiveColors(0)
00062         {}
00063         ~WidgetPropertySetPrivate()
00064         {
00065             delete origActiveColors;
00066         }
00067 
00068         KoProperty::Set  set;
00069         // list of properties (not) to show in editor
00070         QStringList  properties;
00071         // list of widgets
00072         QGuardedWidgetList widgets;
00073 //      FormManager  *manager;
00074 
00075         // used to update command's value when undoing
00076         PropertyCommand  *lastCommand;
00077         GeometryPropertyCommand  *lastGeoCommand;
00078         bool isUndoing : 1;
00079         bool slotPropertyChangedEnabled : 1;
00080         bool slotPropertyChanged_addCommandEnabled : 1;
00081 
00082         // helper to change color palette when switching 'enabled' property
00083         QColorGroup* origActiveColors;
00084 
00085         // i18n stuff
00086         QMap<QCString, QString> propCaption;
00087         QMap<QCString, QString> propValCaption;
00088 };
00089 }
00090 
00091 WidgetPropertySet::WidgetPropertySet(QObject *parent)
00092  : QObject(parent, "kfd_widgetPropertySet")
00093 {
00094     d = new WidgetPropertySetPrivate();
00095 //  d->manager = manager;
00096 
00097     connect(&d->set, SIGNAL(propertyChanged(KoProperty::Set&, KoProperty::Property&)),
00098         this, SLOT(slotPropertyChanged(KoProperty::Set&, KoProperty::Property&)));
00099     connect(&d->set, SIGNAL(propertyReset(KoProperty::Set&, KoProperty::Property&)),
00100         this, SLOT(slotPropertyReset(KoProperty::Set&, KoProperty::Property&)));
00101 
00102     initPropertiesDescription();
00103 }
00104 
00105 WidgetPropertySet::~WidgetPropertySet()
00106 {
00107     delete d;
00108 }
00109 
00110 /*FormManager*
00111 WidgetPropertySet::manager()
00112 {
00113     return d->manager;
00114 }*/
00115 
00116 KoProperty::Property&
00117 WidgetPropertySet::operator[](const QCString &name)
00118 {
00119     return d->set[name];
00120 }
00121 
00122 KoProperty::Property&
00123 WidgetPropertySet::property(const QCString &name)
00124 {
00125     return d->set[name];
00126 }
00127 
00128 bool
00129 WidgetPropertySet::contains(const QCString &property)
00130 {
00131     return d->set.contains(property);
00132 }
00133 
00134 KoProperty::Set*
00135 WidgetPropertySet::set()
00136 {
00137     return &(d->set);
00138 }
00139 
00140 void
00141 WidgetPropertySet::clearSet(bool dontSignalShowPropertySet)
00142 {
00143     saveModifiedProperties();
00144 
00145     if (!dontSignalShowPropertySet)
00146         KFormDesigner::FormManager::self()->showPropertySet(0);
00147     d->widgets.clear();
00148     d->lastCommand = 0;
00149     d->lastGeoCommand = 0;
00150     d->properties.clear();
00151     d->set.clear();
00152 
00153     if(!d->widgets.isEmpty())  {
00154         d->widgets.first()->removeEventFilter(this);
00155         disconnect(d->widgets.first(), 0, this, 0);
00156     }
00157 }
00158 
00159 void
00160 WidgetPropertySet::saveModifiedProperties()
00161 {
00162     QWidget * w = d->widgets.first();
00163     if(!w || d->widgets.count() > 1 || !KFormDesigner::FormManager::self()->activeForm() || !KFormDesigner::FormManager::self()->activeForm()->objectTree())
00164             return;
00165     ObjectTreeItem *tree = KFormDesigner::FormManager::self()->activeForm()->objectTree()->lookup(w->name());
00166     if(!tree)
00167         return;
00168 
00169     for(KoProperty::Set::Iterator it(d->set); it.current(); ++it) {
00170         if(it.current()->isModified())
00171             tree->addModifiedProperty(it.current()->name(), it.current()->oldValue());
00172     }
00173 }
00174 
00175 void
00176 WidgetPropertySet::setUndoing(bool isUndoing)
00177 {
00178     d->isUndoing = isUndoing;
00179 }
00180 
00181 bool
00182 WidgetPropertySet::isUndoing()
00183 {
00184     return d->isUndoing;
00185 }
00186 
00188 
00189 void
00190 WidgetPropertySet::setSelectedWidget(QWidget *w, bool add, bool forceReload, bool moreWillBeSelected)
00191 {
00192     if(!w) {
00193         clearSet();
00194         return;
00195     }
00196 
00197     // don't add a widget twice
00198     if(!forceReload && d->widgets.contains(QGuardedPtr<QWidget>(w))) {
00199         kdWarning() << "WidgetPropertySet::setSelectedWidget() Widget is already selected" << endl;
00200         return;
00201     }
00202     // if our list is empty,don't use add parameter value
00203     if(d->widgets.count() == 0)
00204         add = false;
00205 
00206     QCString prevProperty;
00207     if(add)
00208         addWidget(w);
00209     else {
00210         if (forceReload) {
00211             KFormDesigner::FormManager::self()->showPropertySet(0, true/*force*/);
00212             prevProperty = d->set.prevSelection();
00213         }
00214         clearSet(true); //clear but do not reload to avoid blinking
00215         d->widgets.append(QGuardedPtr<QWidget>(w));
00216         createPropertiesForWidget(w);
00217 
00218         w->installEventFilter(this);
00219         connect(w, SIGNAL(destroyed()), this, SLOT(slotWidgetDestroyed()));
00220     }
00221 
00222     if (!moreWillBeSelected)
00223         KFormDesigner::FormManager::self()->showPropertySet(this, true/*force*/, prevProperty);
00224 }
00225 
00226 void
00227 WidgetPropertySet::addWidget(QWidget *w)
00228 {
00229     d->widgets.append(QGuardedPtr<QWidget>(w));
00230 
00231     // Reset some stuff
00232     d->lastCommand = 0;
00233     d->lastGeoCommand = 0;
00234     d->properties.clear();
00235 
00236     QCString classname;
00237     if(d->widgets.first()->className() == w->className())
00238         classname = d->widgets.first()->className();
00239 
00240     // show only properties shared by widget (properties chosen by factory)
00241     bool isTopLevel = KFormDesigner::FormManager::self()->isTopLevel(w);
00242 
00243     //WidgetWithSubpropertiesInterface* subpropIface = dynamic_cast<WidgetWithSubpropertiesInterface*>(w);
00244 //  QWidget *subwidget = isSubproperty ? subpropIface->subwidget() : w;
00245 
00246     for(KoProperty::Set::Iterator it(d->set); it.current(); ++it) {
00247         kdDebug() << it.currentKey() << endl;
00248         if(!isPropertyVisible(it.currentKey(), isTopLevel, classname))
00249             d->set[it.currentKey()].setVisible(false);
00250     }
00251 
00252     if (d->widgets.count()>=2) {
00253         //second widget, update metainfo
00254         d->set["this:className"].setValue("special:multiple");
00255         d->set["this:classString"].setValue(
00256             i18n("Multiple Widgets") + QString(" (%1)").arg(d->widgets.count()) );
00257         d->set["this:iconName"].setValue("multiple_obj");
00258         //name doesn't make sense for now
00259         d->set["name"].setValue("");
00260     }
00261 }
00262 
00263 void
00264 WidgetPropertySet::createPropertiesForWidget(QWidget *w)
00265 {
00266     Form *form;
00267     if (!KFormDesigner::FormManager::self() 
00268         || !(form = KFormDesigner::FormManager::self()->activeForm()) 
00269         || !KFormDesigner::FormManager::self()->activeForm()->objectTree())
00270     {
00271         kdWarning() << "WidgetPropertySet::createPropertiesForWidget() no manager or active form!!!" << endl;
00272         return;
00273     }
00274     ObjectTreeItem *tree = form->objectTree()->lookup(w->name());
00275     if(!tree)
00276         return;
00277 
00278     const QVariantMap* modifiedProperties = tree->modifiedProperties();
00279     QVariantMapConstIterator modifiedPropertiesIt;
00280     bool isTopLevel = KFormDesigner::FormManager::self()->isTopLevel(w);
00281 //  int count = 0;
00282     KoProperty::Property *newProp = 0;
00283     WidgetInfo *winfo = form->library()->widgetInfoForClassName(w->className());
00284     if (!winfo) {
00285         kdWarning() << "WidgetPropertySet::createPropertiesForWidget() no widget info for class " 
00286             << w->className() << endl;
00287         return;
00288     }
00289 
00290     QStrList pList = w->metaObject()->propertyNames(true);
00291     QStrListIterator it(pList);
00292 
00293     // add subproperties if available
00294     WidgetWithSubpropertiesInterface* subpropIface = dynamic_cast<WidgetWithSubpropertiesInterface*>(w);
00295     QStrList tmpList; //used to allocate copy of names
00296     if (subpropIface) {
00297         QValueList<QCString> subproperies( 
00298             subpropIface->subproperies() );
00299         foreach(QValueListConstIterator<QCString>, it, subproperies ) {
00300             tmpList.append( *it );
00301             pList.append( tmpList.last() );
00302             kdDebug() << "Added subproperty: " << *it << endl;
00303         }
00304     }
00305 
00306     // iterate over the property list, and create Property objects
00307     for(; it.current() != 0; ++it) {
00308         //kdDebug() << ">> " << it.current() << endl;
00309         const QMetaProperty *subMeta = // special case - subproperty
00310             subpropIface ? subpropIface->findMetaSubproperty(it.current()) : 0;
00311         const QMetaProperty *meta = subMeta ? subMeta 
00312              : w->metaObject()->property( w->metaObject()->findProperty(*it, true), true);
00313         if (!meta)
00314             continue;
00315         const char* propertyName = meta->name();
00316         QWidget *subwidget = subMeta/*subpropIface*/ ? subpropIface->subwidget() : w;
00317         WidgetInfo *subwinfo = form->library()->widgetInfoForClassName(subwidget->className());
00318 //      kdDebug() << "$$$ " << subwidget->className() << endl;
00319 
00320         if(subwinfo && meta->designable(subwidget) && !d->set.contains(propertyName)) {
00322             QString desc( d->propCaption[meta->name()] );
00324             if (desc.isEmpty())  //try to get property description from factory
00325                 desc = form->library()->propertyDescForName(subwinfo, propertyName);
00326 
00327             modifiedPropertiesIt = modifiedProperties->find(propertyName);
00328             const bool oldValueExists = modifiedPropertiesIt!=modifiedProperties->constEnd();
00329 
00330             if(meta->isEnumType()) {
00331                 if(qstrcmp(propertyName, "alignment") == 0)  {
00332                     createAlignProperty(meta, w, subwidget);
00333                     continue;
00334                 }
00335 
00336                 QStringList keys = QStringList::fromStrList( meta->enumKeys() );
00337                 newProp = new KoProperty::Property(propertyName, createValueList(subwinfo, keys),
00338                     /* assign current or older value */
00339                     meta->valueToKey( 
00340                         oldValueExists ? modifiedPropertiesIt.data().toInt() : subwidget->property(propertyName).toInt() ), 
00341                     desc, desc );
00342                 //now set current value, so the old one is stored as old
00343                 if (oldValueExists) {
00344                     newProp->setValue( meta->valueToKey( subwidget->property(propertyName).toInt() ) );
00345                 }
00346             }
00347             else {
00348                 newProp = new KoProperty::Property(propertyName, 
00349                     /* assign current or older value */
00350                     oldValueExists ? modifiedPropertiesIt.data() : subwidget->property(propertyName), 
00351                     desc, desc, subwinfo->customTypeForProperty(propertyName));
00352                 //now set current value, so the old one is stored as old
00353                 if (oldValueExists) {
00354                     newProp->setValue( subwidget->property(propertyName) );
00355                 }
00356             }
00357 
00358             d->set.addProperty(newProp);
00359             if(!isPropertyVisible(propertyName, isTopLevel))
00360                 newProp->setVisible(false);
00362             if(newProp->type() == 0) // invalid type == null pixmap ?
00363                 newProp->setType(KoProperty::Pixmap);
00364         }
00365 
00366 //      if(0==qstrcmp(propertyName, "name"))
00367 //          (*this)["name"].setAutoSync(0); // name should be updated only when pressing Enter
00368 
00369         // \todo js what does this mean? why do you use WidgetInfo and not WidgetLibrary
00370         /*if (winfo) {
00371             tristate autoSync = winfo->autoSyncForProperty( propertyName );
00372             if (! ~autoSync)
00373                 d->set[propertyName].setAutoSync( autoSync );
00374         }*/
00375 
00376         // update the Property.oldValue() and isModified() using the value stored in the ObjectTreeItem
00377         updatePropertyValue(tree, propertyName, meta);
00378     }
00379 
00380     (*this)["name"].setAutoSync(false); // name should be updated only when pressing Enter
00381     (*this)["enabled"].setValue( QVariant(tree->isEnabled(), 3));
00382 
00383     if (winfo) {
00384         form->library()->setPropertyOptions(*this, *winfo, w);
00385         d->set.addProperty( newProp = new KoProperty::Property("this:classString", winfo->name()) );
00386         newProp->setVisible(false);
00387         d->set.addProperty( newProp = new KoProperty::Property("this:iconName", winfo->pixmap()) );
00388         newProp->setVisible(false);
00389     }
00390     d->set.addProperty( newProp = new KoProperty::Property("this:className", w->className()) ); 
00391     newProp->setVisible(false);
00392 
00406     if(KFormDesigner::FormManager::self()->activeForm() && tree->container()) // we are a container -> layout property
00407         createLayoutProperty(tree);
00408 }
00409 
00410 void
00411 WidgetPropertySet::updatePropertyValue(ObjectTreeItem *tree, const char *property, const QMetaProperty *meta)
00412 {
00413     const char *propertyName = meta ? meta->name() : property;
00414     if (!d->set.contains(propertyName))
00415         return;
00416     KoProperty::Property p( d->set[propertyName] );
00417 
00419     QMap<QString, QVariant>::ConstIterator it( tree->modifiedProperties()->find(propertyName) );
00420     if (it != tree->modifiedProperties()->constEnd()) {
00421         blockSignals(true);
00422         if(meta && meta->isEnumType()) {
00423             p.setValue( meta->valueToKey( it.data().toInt() ), false );
00424         }
00425         else {
00426             p.setValue(it.data(), false );
00427         }
00428         p.setValue(p.value(), true);
00429         blockSignals(false);
00430     }
00431 }
00432 
00433 bool
00434 WidgetPropertySet::isPropertyVisible(const QCString &property, bool isTopLevel, const QCString &classname)
00435 {
00436     const bool multiple = d->widgets.count() >= 2;
00437     if(multiple && classname.isEmpty())
00438         return false;
00439 /* moved to WidgetLibrary::isPropertyVisible()
00440     if(d->widgets.count() < 2)
00441     {
00442         if(d->properties.isEmpty() && !isTopLevel)
00443             d->properties << "caption" << "icon" << "sizeIncrement" << "iconText";
00444          // don't show these properties for a non-toplevel widget
00445 
00446         if(! (d->properties.grep(property)).isEmpty() )
00447             return false;
00448     }
00449     else
00450     {
00451         if(classname.isEmpty())
00452             return false;
00453 
00454         if(d->properties.isEmpty())  {
00455             d->properties << "font" << "paletteBackgroundColor" << "enabled" << "paletteForegroundColor"
00456                << "cursor" << "paletteBackgroundPixmap";
00457         } // properties always shown in multiple mode
00458         if(! (d->properties.grep(property)).isEmpty() )
00459             return true;
00460     }
00461 */
00462 
00463 //  return KFormDesigner::FormManager::self()->lib()->isPropertyVisible(d->widgets.first()->className(), d->widgets.first(),
00464     QWidget *w = d->widgets.first();
00465     WidgetWithSubpropertiesInterface* subpropIface = dynamic_cast<WidgetWithSubpropertiesInterface*>(w);
00466     QWidget *subwidget;
00467     if (subpropIface && subpropIface->findMetaSubproperty(property)) // special case - subproperty
00468         subwidget = subpropIface->subwidget();
00469     else
00470         subwidget = w;
00471  
00472     return KFormDesigner::FormManager::self()->activeForm()->library()->isPropertyVisible(
00473         subwidget->className(), subwidget, property, multiple, isTopLevel);
00474 }
00475 
00477 
00478 void
00479 WidgetPropertySet::slotPropertyChanged(KoProperty::Set& set, KoProperty::Property& p)
00480 {
00481     Q_UNUSED( set );
00482 
00483     if(!d->slotPropertyChangedEnabled || !KFormDesigner::FormManager::self() || !KFormDesigner::FormManager::self()->activeForm()
00484         || ! KFormDesigner::FormManager::self()->activeForm()->objectTree())
00485         return;
00486 
00487     QCString property = p.name();
00488     if (0==property.find("this:"))
00489         return; //starts with magical prefix: it's a "meta" prop.
00490 
00491     QVariant value = p.value();
00492 
00493     // check if the name is valid (ie is correct identifier) and there is no name conflict
00494     if(property == "name") {
00495         if(d->widgets.count()!=1)
00496             return;
00497         if(!isNameValid(value.toString()))
00498             return;
00499     }
00500     // a widget with a background pixmap should have its own origin
00501     else if(property == "paletteBackgroundPixmap") {
00502         d->set["backgroundOrigin"] = "WidgetOrigin";
00503     //else if(property == "signals")
00504     //  return;
00505     // special types of properties handled separately
00506     } else if((property == "hAlign") || (property == "vAlign") || (property == "wordbreak")) {
00507         saveAlignProperty(property);
00508         return;
00509     }
00510     else if((property == "layout") || (property == "layoutMargin") || (property == "layoutSpacing")) {
00511         saveLayoutProperty(property, value);
00512         return;
00513     }
00514     // we cannot really disable the widget, we just change its color palette
00515     else if(property == "enabled")  {
00516         saveEnabledProperty(value.toBool());
00517         return;
00518     }
00519 
00520      // make sure we are not already undoing -> avoid recursion
00521     if(d->isUndoing && !KFormDesigner::FormManager::self()->isRedoing())
00522         return;
00523 
00524     const bool alterLastCommand = d->lastCommand && d->lastCommand->property() == property;
00525 
00526     if(d->widgets.count() == 1) // one widget selected
00527     {
00528         // If the last command is the same, we just change its value
00529         if(alterLastCommand && !KFormDesigner::FormManager::self()->isRedoing())
00530             d->lastCommand->setValue(value);
00531         else  {
00532 //          if(m_widgets.first() && ((m_widgets.first() != m_manager->activeForm()->widget()) || (property != "geometry"))) {
00533             if (d->slotPropertyChanged_addCommandEnabled && !KFormDesigner::FormManager::self()->isRedoing()) {
00534                 d->lastCommand = new PropertyCommand(this, d->widgets.first()->name(),
00535                         d->widgets.first()->property(property), value, property);
00536                 KFormDesigner::FormManager::self()->activeForm()->addCommand(d->lastCommand, false);
00537             }
00538 
00539             // If the property is changed, we add it in ObjectTreeItem modifProp
00540             ObjectTreeItem *tree = KFormDesigner::FormManager::self()->activeForm()->objectTree()->lookup(d->widgets.first()->name());
00541             if (tree && p.isModified())
00542                 tree->addModifiedProperty(property, d->widgets.first()->property(property));
00543         }
00544 
00545             if(property == "name")
00546                 emit widgetNameChanged(d->widgets.first()->name(), p.value().toCString());
00547             d->widgets.first()->setProperty(property, value);
00548             emitWidgetPropertyChanged(d->widgets.first(), property, value);
00549     }
00550     else
00551     {
00552         if(alterLastCommand && !KFormDesigner::FormManager::self()->isRedoing())
00553             d->lastCommand->setValue(value);
00554         else {
00555             if (d->slotPropertyChanged_addCommandEnabled && !KFormDesigner::FormManager::self()->isRedoing()) {
00556                 // We store old values for each widget
00557                 QMap<QCString, QVariant> list;
00558     //          for(QWidget *w = d->widgets.first(); w; w = d->widgets.next())
00559                 foreach(QGuardedWidgetList::ConstIterator, it, d->widgets)
00560                     list.insert((*it)->name(), (*it)->property(property));
00561 
00562                 d->lastCommand = new PropertyCommand(this, list, value, property);
00563                 KFormDesigner::FormManager::self()->activeForm()->addCommand(d->lastCommand, false);
00564             }
00565         }
00566 
00567 //          for(QWidget *w = d->widgets.first(); w; w = d->widgets.next())
00568         foreach(QGuardedWidgetList::ConstIterator, it, d->widgets) {
00569             if (!alterLastCommand) {
00570                 ObjectTreeItem *tree = KFormDesigner::FormManager::self()->activeForm()->objectTree()
00571                     ->lookup((*it)->name());
00572                 if(tree && p.isModified())
00573                     tree->addModifiedProperty(property, (*it)->property(property));
00574             }
00575             (*it)->setProperty(property, value);
00576             emitWidgetPropertyChanged((*it), property, value);
00577         }
00578     }
00579 }
00580 
00581 void WidgetPropertySet::emitWidgetPropertyChanged(QWidget *w, const QCString& property, const QVariant& value)
00582 {
00583     emit widgetPropertyChanged(w, property, value);
00584 
00585     Form *form = KFormDesigner::FormManager::self()->activeForm();
00586     if (form && form->library()->propertySetShouldBeReloadedAfterPropertyChange( w->className(), w, property)) {
00587         //setSelectedWidget(0, false);
00588         qApp->eventLoop()->processEvents(QEventLoop::AllEvents); //be sure events related to editors are consumed
00589         setSelectedWidget(w, false, /*forceReload*/true);
00590         qApp->eventLoop()->processEvents(QEventLoop::AllEvents); //be sure events related to editors are consumed
00591         //KFormDesigner::FormManager::self()->showPropertySet(this, true/*forceReload*/);
00592     }
00593 }
00594 
00595 void
00596 WidgetPropertySet::createPropertyCommandsInDesignMode(QWidget* widget, 
00597     const QMap<QCString, QVariant> &propValues, CommandGroup *group, bool addToActiveForm,
00598     bool execFlagForSubCommands)
00599 {
00600     if (!widget || propValues.isEmpty())
00601         return;
00602     
00603     //is this widget selected? (if so, use property system)
00604     const bool widgetIsSelected = KFormDesigner::FormManager::self()->activeForm()->selectedWidget() == widget;
00605 
00606     d->slotPropertyChanged_addCommandEnabled = false;
00607     QMap<QCString, QVariant>::ConstIterator endIt = propValues.constEnd();
00608 //  CommandGroup *group = new CommandGroup(commandName);
00609     for(QMap<QCString, QVariant>::ConstIterator it = propValues.constBegin(); it != endIt; ++it)
00610     {
00611         if (!d->set.contains(it.key())) {
00612             kdWarning() << "WidgetPropertySet::createPropertyCommandsInDesignMode(): \"" <<it.key()<<"\" property not found"<<endl;
00613             continue;
00614         }
00615         PropertyCommand *subCommand = new PropertyCommand(this, widget->name(),
00616             widget->property(it.key()), it.data(), it.key());
00617         group->addCommand( subCommand, execFlagForSubCommands);
00618         if (widgetIsSelected) {
00619             d->set[it.key()].setValue(it.data());
00620         }
00621         else {
00622             WidgetWithSubpropertiesInterface* subpropIface = dynamic_cast<WidgetWithSubpropertiesInterface*>(widget);
00623             QWidget *subwidget = (subpropIface && subpropIface->subwidget()) ? subpropIface->subwidget() : widget;
00624             if (-1 != subwidget->metaObject()->findProperty(it.key(), true) && subwidget->property(it.key())!=it.data()) {
00625                 ObjectTreeItem *tree = KFormDesigner::FormManager::self()->activeForm()->objectTree()->lookup(widget->name());
00626                 if (tree)
00627                     tree->addModifiedProperty(it.key(), subwidget->property(it.key()));
00628                 subwidget->setProperty(it.key(), it.data());
00629                 emit widgetPropertyChanged(widget, it.key(), it.data());
00630             }
00631         }
00632     }
00633     d->lastCommand = 0;
00634     if (addToActiveForm)
00635         KFormDesigner::FormManager::self()->activeForm()->addCommand(group, false/*no exec*/);
00636     d->slotPropertyChanged_addCommandEnabled = true;
00637 //  }
00638 }
00639 
00641 void
00642 WidgetPropertySet::saveEnabledProperty(bool value)
00643 {
00644 //  for(QWidget *w = d->widgets.first(); w; w = d->widgets.next()) {
00645     foreach(QGuardedWidgetList::ConstIterator, it, d->widgets) {
00646         ObjectTreeItem *tree = KFormDesigner::FormManager::self()->activeForm()->objectTree()
00647             ->lookup((*it)->name());
00648         if(tree->isEnabled() == value)
00649             continue;
00650 
00651         QPalette p( (*it)->palette() );
00652         if (!d->origActiveColors)
00653             d->origActiveColors = new QColorGroup( p.active() );
00654         if (value) {
00655             if (d->origActiveColors)
00656                 p.setActive( *d->origActiveColors ); //revert
00657         }
00658         else {
00659             QColorGroup cg = p.disabled();
00660             //also make base color a bit disabled-like
00661             cg.setColor(QColorGroup::Base, cg.color(QColorGroup::Background));
00662             p.setActive(cg);
00663         }
00664         (*it)->setPalette(p);
00665 
00666         tree->setEnabled(value);
00667         emit widgetPropertyChanged((*it), "enabled", QVariant(value, 3));
00668     }
00669 }
00670 
00671 bool
00672 WidgetPropertySet::isNameValid(const QString &name)
00673 {
00675     QWidget *w = d->widgets.first();
00676     //also update widget's name in QObject member
00677     if (!KexiUtils::isIdentifier(name)) {
00678         KMessageBox::sorry(KFormDesigner::FormManager::self()->activeForm()->widget(),
00679             i18n("Could not rename widget \"%1\" to \"%2\" because "
00680             "\"%3\" is not a valid name (identifier) for a widget.\n")
00681             .arg(w->name()).arg(name).arg(name));
00682         d->slotPropertyChangedEnabled = false;
00683         d->set["name"].resetValue();
00684         d->slotPropertyChangedEnabled = true;
00685         return false;
00686     }
00687 
00688     if (KFormDesigner::FormManager::self()->activeForm()->objectTree()->lookup(name)) {
00689         KMessageBox::sorry( KFormDesigner::FormManager::self()->activeForm()->widget(),
00690             i18n("Could not rename widget \"%1\" to \"%2\" "
00691             "because a widget with the name \"%3\" already exists.\n")
00692             .arg(w->name()).arg(name).arg(name));
00693         d->slotPropertyChangedEnabled = false;
00694         d->set["name"].resetValue();
00695         d->slotPropertyChangedEnabled = true;
00696         return false;
00697     }
00698 
00699     return true; //ie name is correct
00700 }
00701 
00702 void
00703 WidgetPropertySet::slotPropertyReset(KoProperty::Set& set, KoProperty::Property& property)
00704 {
00705     Q_UNUSED( set );
00706 
00707     if(d->widgets.count() < 2)
00708         return;
00709 
00710     // We use the old value in modifProp for each widget
00711 //  for(QWidget *w = d->widgets.first(); w; w = d->widgets.next())  {
00712     foreach(QGuardedWidgetList::ConstIterator, it, d->widgets) {
00713         ObjectTreeItem *tree = KFormDesigner::FormManager::self()->activeForm()->objectTree()->lookup((*it)->name());
00714         if(tree->modifiedProperties()->contains(property.name()))
00715             (*it)->setProperty(property.name(), tree->modifiedProperties()->find(property.name()).data());
00716     }
00717 }
00718 
00719 void
00720 WidgetPropertySet::slotWidgetDestroyed()
00721 {
00722 //  if(d->widgets.contains(QGuardedPtr<const QWidget>( dynamic_cast<const QWidget*>(sender()) ))) {
00723     //only clear this set if it contains the destroyed widget
00724     foreach(QGuardedWidgetList::ConstIterator, it, d->widgets) {
00725         if (dynamic_cast<const QWidget*>(sender()) == *it) {
00726             clearSet();
00727             break;
00728         }
00729     }
00730 }
00731 
00732 bool
00733 WidgetPropertySet::eventFilter(QObject *o, QEvent *ev)
00734 {
00735     if(d->widgets.count() > 0 && o == d->widgets.first() && d->widgets.count() < 2)
00736     {
00737         if((ev->type() == QEvent::Resize) || (ev->type() == QEvent::Move))  {
00738             if(!d->set.contains("geometry"))
00739                 return false;
00740             if(d->set["geometry"].value() == o->property("geometry")) // to avoid infinite recursion
00741                 return false;
00742 
00743             d->set["geometry"] = static_cast<QWidget*>(o)->geometry();
00744         }
00745     }
00746     else if(d->widgets.count() > 1 && ev->type() == QEvent::Move) // the widget is being moved, we update the property
00747     {
00748         if(d->isUndoing)
00749             return false;
00750 
00751         if(d->lastGeoCommand)
00752             d->lastGeoCommand->setPos(static_cast<QMoveEvent*>(ev)->pos());
00753         else  {
00754             QStringList list;
00755             foreach(QGuardedWidgetList::ConstIterator, it, d->widgets)
00756                 list.append((*it)->name());
00757 
00758             d->lastGeoCommand = new GeometryPropertyCommand(this, list, static_cast<QMoveEvent*>(ev)->oldPos());
00759             if (KFormDesigner::FormManager::self()->activeForm())
00760                 KFormDesigner::FormManager::self()->activeForm()->addCommand(d->lastGeoCommand, false);
00761         }
00762     }
00763 
00764     return false;
00765 }
00766 
00767 // Alignment-related functions /////////////////////////////
00768 
00769 void
00770 WidgetPropertySet::createAlignProperty(const QMetaProperty *meta, QWidget *widget, QWidget *subwidget)
00771 {
00772     if (!KFormDesigner::FormManager::self()->activeForm() 
00773 || !KFormDesigner::FormManager::self()->activeForm()->objectTree())
00774         return;
00775 
00776     QStringList list;
00777     QString value;
00778     const int alignment = subwidget->property("alignment").toInt();
00779     QStringList keys = QStringList::fromStrList( meta->valueToKeys(alignment) );
00780 
00781     QStrList *enumKeys = new QStrList(meta->enumKeys());
00782     QStringList possibleValues = QStringList::fromStrList(*enumKeys);
00783     delete enumKeys;
00784 
00785     ObjectTreeItem *tree = KFormDesigner::FormManager::self()->activeForm()->objectTree()->lookup(widget->name());
00786     bool isTopLevel = KFormDesigner::FormManager::self()->isTopLevel(widget);
00787 
00788     if(!possibleValues.grep("AlignHCenter").empty())  {
00789         // Create the horizontal alignment property
00790         if(!keys.grep("AlignHCenter").isEmpty())
00791             value = "AlignHCenter";
00792         else if(!keys.grep("AlignRight").isEmpty())
00793             value = "AlignRight";
00794         else if(!keys.grep("AlignLeft").isEmpty())
00795             value = "AlignLeft";
00796         else if(!keys.grep("AlignJustify").isEmpty())
00797             value = "AlignJustify";
00798         else
00799             value = "AlignAuto";
00800 
00801         list << "AlignAuto" << "AlignLeft" << "AlignRight" << "AlignHCenter" << "AlignJustify";
00802         KoProperty::Property *p = new KoProperty::Property("hAlign", createValueList(0, list), value,
00803             i18n("Translators: please keep this string short (less than 20 chars)", "Hor. Alignment"),
00804             i18n("Horizontal Alignment"));
00805         d->set.addProperty(p);
00806         if(!isPropertyVisible(p->name(), isTopLevel)) {
00807             p->setVisible(false);
00808         }
00809         updatePropertyValue(tree, "hAlign");
00810         list.clear();
00811     }
00812 
00813     if(!possibleValues.grep("AlignTop").empty())
00814     {
00815         // Create the ver alignment property
00816         if(!keys.grep("AlignTop").empty())
00817             value = "AlignTop";
00818         else if(!keys.grep("AlignBottom").empty())
00819             value = "AlignBottom";
00820         else
00821             value = "AlignVCenter";
00822 
00823         list << "AlignTop" << "AlignVCenter" << "AlignBottom";
00824         KoProperty::Property *p = new KoProperty::Property("vAlign", createValueList(0, list), value,
00825             i18n("Translators: please keep this string short (less than 20 chars)", "Ver. Alignment"),
00826             i18n("Vertical Alignment"));
00827         d->set.addProperty(p);
00828         if(!isPropertyVisible(p->name(), isTopLevel)) {
00829             p->setVisible(false);
00830         }
00831         updatePropertyValue(tree, "vAlign");
00832     }
00833     
00834 
00835     if(!possibleValues.grep("WordBreak").empty()
00836 //      && isPropertyVisible("wordbreak", false, subwidget->className())
00837 //    && !subWidget->inherits("QLineEdit") /* QLineEdit doesn't support 'word break' is this generic enough?*/
00838     ) {
00839         // Create the wordbreak property
00840         KoProperty::Property *p = new KoProperty::Property("wordbreak", 
00841             QVariant(alignment & Qt::WordBreak, 3), i18n("Word Break"), i18n("Word Break") );
00842         d->set.addProperty(p);
00843         updatePropertyValue(tree, "wordbreak");
00844         if (!KFormDesigner::FormManager::self()->activeForm()->library()->isPropertyVisible(
00845             subwidget->className(), subwidget, p->name(), false/*multiple*/, isTopLevel))
00846         {
00847             p->setVisible(false);
00848         }
00849     }
00850 }
00851 
00852 void
00853 WidgetPropertySet::saveAlignProperty(const QString &property)
00854 {
00855     if (!KFormDesigner::FormManager::self()->activeForm())
00856         return;
00857 
00858     QStrList list;
00859     if( d->set.contains("hAlign") )
00860         list.append( d->set["hAlign"].value().toCString() );
00861     if( d->set.contains("vAlign") )
00862         list.append( d->set["vAlign"].value().toCString() );
00863     if( d->set.contains("wordbreak") && d->set["wordbreak"].value().toBool() )
00864         list.append("WordBreak");
00865 
00866     WidgetWithSubpropertiesInterface* subpropIface = dynamic_cast<WidgetWithSubpropertiesInterface*>(
00867         (QWidget*)d->widgets.first() );
00868     QWidget *subwidget = (subpropIface && subpropIface->subwidget()) ? subpropIface->subwidget() : (QWidget*)d->widgets.first();
00869     int count = subwidget->metaObject()->findProperty("alignment", true);
00870     const QMetaProperty *meta = subwidget->metaObject()->property(count, true);
00871     subwidget->setProperty("alignment", meta->keysToValue(list));
00872 
00873     ObjectTreeItem *tree = KFormDesigner::FormManager::self()->activeForm()->objectTree()->lookup(
00874         d->widgets.first()->name() );
00875     if(tree && d->set[property.latin1()].isModified())
00876         tree->addModifiedProperty(property.latin1(), d->set[property.latin1()].oldValue());
00877 
00878     if(d->isUndoing)
00879         return;
00880 
00881     if(d->lastCommand && d->lastCommand->property() == "alignment")
00882         d->lastCommand->setValue(meta->keysToValue(list));
00883     else {
00884         d->lastCommand = new PropertyCommand(this, d->widgets.first()->name(),
00885             subwidget->property("alignment"), meta->keysToValue(list), "alignment");
00886         KFormDesigner::FormManager::self()->activeForm()->addCommand(d->lastCommand, false);
00887     }
00888 }
00889 
00890 // Layout-related functions  //////////////////////////
00891 
00892 void
00893 WidgetPropertySet::createLayoutProperty(ObjectTreeItem *item)
00894 {
00895     Container *container = item->container();
00896     if (!container || !KFormDesigner::FormManager::self()->activeForm() ||
00897         !KFormDesigner::FormManager::self()->activeForm()->objectTree() || !container->widget())
00898         return;
00899     // special containers have no 'layout' property, as it should not be changed
00900     QCString className = container->widget()->className();
00901     if((className == "HBox") || (className == "VBox") || (className == "Grid"))
00902         return;
00903 
00904     QStringList list;
00905     QString value = Container::layoutTypeToString(container->layoutType());
00906 
00907     list << "NoLayout" << "HBox" << "VBox" << "Grid" << "HFlow" << "VFlow";
00908 
00909     KoProperty::Property *p = new KoProperty::Property("layout", createValueList(0, list), value,
00910         i18n("Container's Layout"), i18n("Container's Layout"));
00911     p->setVisible( container->form()->library()->advancedPropertiesVisible() );
00912     d->set.addProperty(p);
00913 
00914     updatePropertyValue(item, "layout");
00915 
00916     p = new KoProperty::Property("layoutMargin", container->layoutMargin(), i18n("Layout Margin"), i18n("Layout Margin"));
00917     d->set.addProperty(p);
00918     updatePropertyValue(item, "layoutMargin");
00919     if(container->layoutType() == Container::NoLayout)
00920         p->setVisible(false);
00921 
00922     p = new KoProperty::Property("layoutSpacing", container->layoutSpacing(), 
00923         i18n("Layout Spacing"), i18n("Layout Spacing"));
00924     d->set.addProperty(p);
00925     updatePropertyValue(item, "layoutSpacing");
00926     if(container->layoutType() == Container::NoLayout)
00927         p->setVisible(false);
00928 
00929 }
00930 
00931 void
00932 WidgetPropertySet::saveLayoutProperty(const QString &prop, const QVariant &value)
00933 {
00934     Container *container=0;
00935     if(!KFormDesigner::FormManager::self()->activeForm() || !KFormDesigner::FormManager::self()->activeForm()->objectTree())
00936         return;
00937     ObjectTreeItem *item = KFormDesigner::FormManager::self()->activeForm()->objectTree()->lookup(d->widgets.first()->name());
00938     if(!item)
00939         return;
00940     container = item->container();
00941 
00942     if(prop == "layout") {
00943         Container::LayoutType type = Container::stringToLayoutType(value.toString());
00944 
00945         if(d->lastCommand && d->lastCommand->property() == "layout" && !d->isUndoing)
00946             d->lastCommand->setValue(value);
00947         else if(!d->isUndoing)  {
00948             d->lastCommand = new LayoutPropertyCommand(this, d->widgets.first()->name(),
00949                 d->set["layout"].oldValue(), value);
00950             KFormDesigner::FormManager::self()->activeForm()->addCommand(d->lastCommand, false);
00951         }
00952 
00953         container->setLayout(type);
00954         bool show = (type != Container::NoLayout);
00955         if(show != d->set["layoutMargin"].isVisible())  {
00956             d->set["layoutMargin"].setVisible(show);
00957             d->set["layoutSpacing"].setVisible(show);
00958             KFormDesigner::FormManager::self()->showPropertySet(this, true/*force*/);
00959         }
00960         return;
00961     }
00962 
00963     if(prop == "layoutMargin" && container->layout()) {
00964         container->setLayoutMargin(value.toInt());
00965         container->layout()->setMargin(value.toInt());
00966     }
00967     else if(prop == "layoutSpacing" && container->layout())  {
00968         container->setLayoutSpacing(value.toInt());
00969         container->layout()->setSpacing(value.toInt());
00970     }
00971 
00972     ObjectTreeItem *tree = KFormDesigner::FormManager::self()->activeForm()->objectTree()->lookup(d->widgets.first()->name());
00973     if(tree && d->set[ prop.latin1() ].isModified())
00974         tree->addModifiedProperty(prop.latin1(), d->set[prop.latin1()].oldValue());
00975 
00976     if(d->isUndoing)
00977         return;
00978 
00979     if(d->lastCommand && (QString(d->lastCommand->property()) == prop))
00980         d->lastCommand->setValue(value);
00981     else  {
00982         d->lastCommand = new PropertyCommand(this, d->widgets.first()->name(),
00983             d->set[ prop.latin1() ].oldValue(), value, prop.latin1());
00984         KFormDesigner::FormManager::self()->activeForm()->addCommand(d->lastCommand, false);
00985     }
00986 }
00987 
00988 
00989 
00991 
00992 void
00993 WidgetPropertySet::initPropertiesDescription()
00994 {
00997     d->propCaption["name"] = i18n("Name");
00998     d->propCaption["caption"] = i18n("Caption");
00999     d->propCaption["text"] = i18n("Text");
01000     d->propCaption["paletteBackgroundPixmap"] = i18n("Background Pixmap");
01001     d->propCaption["enabled"] = i18n("Enabled");
01002     d->propCaption["geometry"] = i18n("Geometry");
01003     d->propCaption["sizePolicy"] = i18n("Size Policy");
01004     d->propCaption["minimumSize"] = i18n("Minimum Size");
01005     d->propCaption["maximumSize"] = i18n("Maximum Size");
01006     d->propCaption["font"] = i18n("Font");
01007     d->propCaption["cursor"] = i18n("Cursor");
01008     d->propCaption["paletteForegroundColor"] = i18n("Foreground Color");
01009     d->propCaption["paletteBackgroundColor"] = i18n("Background Color");
01010     d->propCaption["focusPolicy"] = i18n("Focus Policy");
01011     d->propCaption["margin"] = i18n("Margin");
01012     d->propCaption["readOnly"] = i18n("Read Only");
01013     //any QFrame
01014     d->propCaption["frame"] = i18n("Frame");
01015     d->propCaption["lineWidth"] = i18n("Frame Width");
01016     d->propCaption["midLineWidth"] = i18n("Mid Frame Width");
01017     d->propCaption["frameShape"] = i18n("Frame Shape");
01018     d->propCaption["frameShadow"] = i18n("Frame Shadow");
01019     //any QScrollbar
01020     d->propCaption["vScrollBarMode"] = i18n("Vertical ScrollBar");
01021     d->propCaption["hScrollBarMode"] = i18n("Horizontal ScrollBar");
01022 
01023     d->propValCaption["NoBackground"] = i18n("No Background");
01024     d->propValCaption["PaletteForeground"] = i18n("Palette Foreground");
01025     d->propValCaption["AutoText"] = i18n("Auto (HINT: for AutoText)", "Auto");
01026 
01027     d->propValCaption["AlignAuto"] = i18n("Auto (HINT: for Align)", "Auto");
01028     d->propValCaption["AlignLeft"] = i18n("Left (HINT: for Align)", "Left");
01029     d->propValCaption["AlignRight"] = i18n("Right (HINT: for Align)", "Right");
01030     d->propValCaption["AlignHCenter"] = i18n("Center (HINT: for Align)", "Center");
01031     d->propValCaption["AlignJustify"] = i18n("Justify (HINT: for Align)", "Justify");
01032     d->propValCaption["AlignVCenter"] = i18n("Center (HINT: for Align)", "Center");
01033     d->propValCaption["AlignTop"] = i18n("Top (HINT: for Align)", "Top");
01034     d->propValCaption["AlignBottom"] = i18n("Bottom (HINT: for Align)", "Bottom");
01035 
01036     d->propValCaption["NoFrame"] = i18n("No Frame (HINT: for Frame Shape)", "No Frame");
01037     d->propValCaption["Box"] = i18n("Box (HINT: for Frame Shape)", "Box");
01038     d->propValCaption["Panel"] = i18n("Panel (HINT: for Frame Shape)", "Panel");
01039     d->propValCaption["WinPanel"] = i18n("Windows Panel (HINT: for Frame Shape)", "Windows Panel");
01040     d->propValCaption["HLine"] = i18n("Horiz. Line (HINT: for Frame Shape)", "Horiz. Line");
01041     d->propValCaption["VLine"] = i18n("Vertical Line (HINT: for Frame Shape)", "Vertical Line");
01042     d->propValCaption["StyledPanel"] = i18n("Styled (HINT: for Frame Shape)", "Styled");
01043     d->propValCaption["PopupPanel"] = i18n("Popup (HINT: for Frame Shape)", "Popup");
01044     d->propValCaption["MenuBarPanel"] = i18n("Menu Bar (HINT: for Frame Shape)", "Menu Bar");
01045     d->propValCaption["ToolBarPanel"] = i18n("Toolbar (HINT: for Frame Shape)", "Toolbar");
01046     d->propValCaption["LineEditPanel"] = i18n("Text Box (HINT: for Frame Shape)", "Text Box");
01047     d->propValCaption["TabWidgetPanel"] = i18n("Tab Widget (HINT: for Frame Shape)", "Tab Widget");
01048     d->propValCaption["GroupBoxPanel"] = i18n("Group Box (HINT: for Frame Shape)", "Group Box");
01049 
01050     d->propValCaption["Plain"] = i18n("Plain (HINT: for Frame Shadow)", "Plain");
01051     d->propValCaption["Raised"] = i18n("Raised (HINT: for Frame Shadow)", "Raised");
01052     d->propValCaption["Sunken"] = i18n("Sunken (HINT: for Frame Shadow)", "Sunken");
01053     d->propValCaption["MShadow"] = i18n("for Frame Shadow", "Internal");
01054 
01055     d->propValCaption["NoFocus"] = i18n("No Focus (HINT: for Focus)", "No Focus");
01056     d->propValCaption["TabFocus"] = i18n("Tab (HINT: for Focus)", "Tab");
01057     d->propValCaption["ClickFocus"] = i18n("Click (HINT: for Focus)", "Click");
01058     d->propValCaption["StrongFocus"] = i18n("Tab/Click (HINT: for Focus)", "Tab/Click");
01059     d->propValCaption["WheelFocus"] = i18n("Tab/Click/MouseWheel (HINT: for Focus)", "Tab/Click/MouseWheel");
01060 
01061     d->propValCaption["Auto"] = i18n("Auto");
01062     d->propValCaption["AlwaysOff"] = i18n("Always Off");
01063     d->propValCaption["AlwaysOn"] = i18n("Always On");
01064 
01065     //orientation
01066     d->propValCaption["Horizontal"] = i18n("Horizontal");
01067     d->propValCaption["Vertical"] = i18n("Vertical");
01068 }
01069 
01070 QString
01071 WidgetPropertySet::propertyCaption(const QCString &name)
01072 {
01073     return d->propCaption[name];
01074 }
01075 
01076 QString
01077 WidgetPropertySet::valueCaption(const QCString &name)
01078 {
01079     return d->propValCaption[name];
01080 }
01081 
01082 KoProperty::Property::ListData*
01083 WidgetPropertySet::createValueList(WidgetInfo *winfo, const QStringList &list)
01084 {
01085 //  QMap <QString, QVariant> map;
01086     QStringList names;
01087     QStringList::ConstIterator endIt = list.end();
01088     for(QStringList::ConstIterator it = list.begin(); it != endIt; ++it) {
01089         QString n( d->propValCaption[ (*it).latin1() ] );
01090         if (n.isEmpty()) { //try within factory and (maybe) parent factory
01091             if (winfo)
01092                 n = KFormDesigner::FormManager::self()->activeForm()->library()->propertyDescForValue( winfo, (*it).latin1() );
01093             if (n.isEmpty())
01094                 names.append( *it ); //untranslated
01095 //              map.insert(*it, (*it).latin1()); //untranslated
01096             else
01097                 names.append( n );
01098 //              map.insert(*it, n);
01099         }
01100         else
01101             names.append( n );
01102 //          map.insert(*it, n);
01103     }
01104     return new KoProperty::Property::ListData(list, names);
01105 }
01106 
01107 void
01108 WidgetPropertySet::addPropertyCaption(const QCString &property, const QString &caption)
01109 {
01110     if(!d->propCaption.contains(property))
01111         d->propCaption[property] = caption;
01112 }
01113 
01114 void
01115 WidgetPropertySet::addValueCaption(const QCString &value, const QString &caption)
01116 {
01117     if(!d->propValCaption.contains(value))
01118         d->propValCaption[value] = caption;
01119 }
01120 
01121 #include "widgetpropertyset.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys