00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
00070 QStringList properties;
00071
00072 QGuardedWidgetList widgets;
00073
00074
00075
00076 PropertyCommand *lastCommand;
00077 GeometryPropertyCommand *lastGeoCommand;
00078 bool isUndoing : 1;
00079 bool slotPropertyChangedEnabled : 1;
00080 bool slotPropertyChanged_addCommandEnabled : 1;
00081
00082
00083 QColorGroup* origActiveColors;
00084
00085
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
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
00111
00112
00113
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
00198 if(!forceReload && d->widgets.contains(QGuardedPtr<QWidget>(w))) {
00199 kdWarning() << "WidgetPropertySet::setSelectedWidget() Widget is already selected" << endl;
00200 return;
00201 }
00202
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);
00212 prevProperty = d->set.prevSelection();
00213 }
00214 clearSet(true);
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, prevProperty);
00224 }
00225
00226 void
00227 WidgetPropertySet::addWidget(QWidget *w)
00228 {
00229 d->widgets.append(QGuardedPtr<QWidget>(w));
00230
00231
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
00241 bool isTopLevel = KFormDesigner::FormManager::self()->isTopLevel(w);
00242
00243
00244
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
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
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
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
00294 WidgetWithSubpropertiesInterface* subpropIface = dynamic_cast<WidgetWithSubpropertiesInterface*>(w);
00295 QStrList tmpList;
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
00307 for(; it.current() != 0; ++it) {
00308
00309 const QMetaProperty *subMeta =
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->subwidget() : w;
00317 WidgetInfo *subwinfo = form->library()->widgetInfoForClassName(subwidget->className());
00318
00319
00320 if(subwinfo && meta->designable(subwidget) && !d->set.contains(propertyName)) {
00322 QString desc( d->propCaption[meta->name()] );
00324 if (desc.isEmpty())
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
00339 meta->valueToKey(
00340 oldValueExists ? modifiedPropertiesIt.data().toInt() : subwidget->property(propertyName).toInt() ),
00341 desc, desc );
00342
00343 if (oldValueExists) {
00344 newProp->setValue( meta->valueToKey( subwidget->property(propertyName).toInt() ) );
00345 }
00346 }
00347 else {
00348 newProp = new KoProperty::Property(propertyName,
00349
00350 oldValueExists ? modifiedPropertiesIt.data() : subwidget->property(propertyName),
00351 desc, desc, subwinfo->customTypeForProperty(propertyName));
00352
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)
00363 newProp->setType(KoProperty::Pixmap);
00364 }
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377 updatePropertyValue(tree, propertyName, meta);
00378 }
00379
00380 (*this)["name"].setAutoSync(false);
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())
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
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464 QWidget *w = d->widgets.first();
00465 WidgetWithSubpropertiesInterface* subpropIface = dynamic_cast<WidgetWithSubpropertiesInterface*>(w);
00466 QWidget *subwidget;
00467 if (subpropIface && subpropIface->findMetaSubproperty(property))
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;
00490
00491 QVariant value = p.value();
00492
00493
00494 if(property == "name") {
00495 if(d->widgets.count()!=1)
00496 return;
00497 if(!isNameValid(value.toString()))
00498 return;
00499 }
00500
00501 else if(property == "paletteBackgroundPixmap") {
00502 d->set["backgroundOrigin"] = "WidgetOrigin";
00503
00504
00505
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
00515 else if(property == "enabled") {
00516 saveEnabledProperty(value.toBool());
00517 return;
00518 }
00519
00520
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)
00527 {
00528
00529 if(alterLastCommand && !KFormDesigner::FormManager::self()->isRedoing())
00530 d->lastCommand->setValue(value);
00531 else {
00532
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
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
00557 QMap<QCString, QVariant> list;
00558
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
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
00588 qApp->eventLoop()->processEvents(QEventLoop::AllEvents);
00589 setSelectedWidget(w, false, true);
00590 qApp->eventLoop()->processEvents(QEventLoop::AllEvents);
00591
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
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
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);
00636 d->slotPropertyChanged_addCommandEnabled = true;
00637
00638 }
00639
00641 void
00642 WidgetPropertySet::saveEnabledProperty(bool value)
00643 {
00644
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 );
00657 }
00658 else {
00659 QColorGroup cg = p.disabled();
00660
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
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;
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
00711
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
00723
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"))
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)
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
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
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
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
00837
00838 ) {
00839
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, 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
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
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);
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
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
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
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
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()) {
01091 if (winfo)
01092 n = KFormDesigner::FormManager::self()->activeForm()->library()->propertyDescForValue( winfo, (*it).latin1() );
01093 if (n.isEmpty())
01094 names.append( *it );
01095
01096 else
01097 names.append( n );
01098
01099 }
01100 else
01101 names.append( n );
01102
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"