File indexing completed on 2024-05-12 16:39:51
0001 /* This file is part of the KDE project 0002 Copyright (C) 2003 Lucijan Busch <lucijan@gmx.at> 0003 Copyright (C) 2004 Cedric Pasteur <cedric.pasteur@free.fr> 0004 Copyright (C) 2004-2009 Jarosław Staniek <staniek@kde.org> 0005 0006 This library is free software; you can redistribute it and/or 0007 modify it under the terms of the GNU Library General Public 0008 License as published by the Free Software Foundation; either 0009 version 2 of the License, or (at your option) any later version. 0010 0011 This library is distributed in the hope that it will be useful, 0012 but WITHOUT ANY WARRANTY; without even the implied warranty of 0013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0014 Library General Public License for more details. 0015 0016 You should have received a copy of the GNU Library General Public License 0017 along with this library; see the file COPYING.LIB. If not, write to 0018 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0019 * Boston, MA 02110-1301, USA. 0020 */ 0021 0022 #include "widgetfactory.h" 0023 0024 #include <KEditListWidget> 0025 #include <KLocalizedString> 0026 0027 #include "richtextdialog.h" 0028 #ifdef KEXI_LIST_FORM_WIDGET_SUPPORT 0029 # include "editlistviewdialog.h" 0030 #endif 0031 0032 #include "form.h" 0033 #include "container.h" 0034 #include "objecttree.h" 0035 #include "widgetlibrary.h" 0036 #include "WidgetInfo.h" 0037 #include "widgetwithsubpropertiesinterface.h" 0038 #include "utils.h" 0039 #include <kexiutils/utils.h> 0040 0041 #include <KProperty> 0042 #include <KPropertySet> 0043 0044 #include <QDialog> 0045 #include <QVBoxLayout> 0046 #include <QDialogButtonBox> 0047 #include <QDebug> 0048 0049 using namespace KFormDesigner; 0050 0051 InternalPropertyHandlerInterface::InternalPropertyHandlerInterface() 0052 { 0053 } 0054 0055 InternalPropertyHandlerInterface::~InternalPropertyHandlerInterface() 0056 { 0057 } 0058 0059 ///// InlineEditorCreationArguments ////////////////////////// 0060 0061 WidgetFactory::InlineEditorCreationArguments::InlineEditorCreationArguments( 0062 const QByteArray& _classname, QWidget *_widget, Container *_container) 0063 : classname(_classname), widget(_widget), container(_container), 0064 geometry(_widget ? _widget->geometry() : QRect()), 0065 alignment( Qt::AlignLeft ), 0066 useFrame( false ), multiLine( false ), execute( true ), transparentBackground( false ) 0067 { 0068 } 0069 0070 ///// Widget Factory ////////////////////////// 0071 0072 class Q_DECL_HIDDEN WidgetFactory::Private 0073 { 0074 public: 0075 Private(); 0076 ~Private(); 0077 0078 WidgetLibrary *library; 0079 0080 QHash<QByteArray, WidgetInfo*> classesByName; 0081 QSet<QByteArray>* hiddenClasses; 0082 0083 //! i18n stuff 0084 QHash<QByteArray, QString> propDesc; 0085 QHash<QByteArray, QString> propValDesc; 0086 //! internal properties 0087 QHash<QByteArray, QVariant> internalProp; 0088 0089 /*! flag useful to decide whether to hide some properties. 0090 It's value is inherited from WidgetLibrary. */ 0091 bool advancedPropertiesVisible; 0092 }; 0093 0094 WidgetFactory::Private::Private() 0095 : hiddenClasses(0), advancedPropertiesVisible(true) 0096 { 0097 0098 } 0099 0100 WidgetFactory::Private::~Private() 0101 { 0102 qDeleteAll(classesByName); 0103 delete hiddenClasses; 0104 } 0105 0106 WidgetFactory::WidgetFactory(QObject *parent) 0107 : QObject(parent), d(new Private()) 0108 { 0109 } 0110 0111 WidgetFactory::~WidgetFactory() 0112 { 0113 delete d; 0114 } 0115 0116 void WidgetFactory::addClass(WidgetInfo *w) 0117 { 0118 WidgetInfo *oldw = d->classesByName.value(w->className()); 0119 if (oldw == w) 0120 return; 0121 if (oldw) { 0122 qWarning() << "class with name '" 0123 << w->className() 0124 << "' already exists for factory '" << objectName() << "'"; 0125 return; 0126 } 0127 d->classesByName.insert(w->className(), w); 0128 } 0129 0130 void WidgetFactory::hideClass(const char *classname) 0131 { 0132 if (!d->hiddenClasses) 0133 d->hiddenClasses = new QSet<QByteArray>; 0134 d->hiddenClasses->insert(QByteArray(classname).toLower()); 0135 } 0136 0137 QHash<QByteArray, WidgetInfo*> WidgetFactory::classes() const 0138 { 0139 return d->classesByName; 0140 } 0141 0142 void WidgetFactory::disableFilter(QWidget *w, Container *container) 0143 { 0144 container->form()->disableFilter(w, container); 0145 } 0146 0147 bool WidgetFactory::editList(QWidget *w, QStringList &list) const 0148 { 0149 //! @todo KEXI3 port to QDialog 0150 #if 1 0151 Q_UNUSED(w); 0152 Q_UNUSED(list); 0153 #else 0154 QDialog dialog(w->topLevelWidget()); 0155 dialog.setObjectName("stringlist_dialog"); 0156 dialog.setModal(true); 0157 dialog.setWindowTitle(xi18nc("@title:window", "Edit Contents of %1", w->objectName())); 0158 dialog.setButtons(QDialog::Ok | QDialog::Cancel); 0159 0160 QVBoxLayout *mainLayout = new QVBoxLayout; 0161 dialog.setLayout(mainLayout); 0162 KEditListWidget *edit = new KEditListWidget(&dialog); 0163 edit->setObjectName("editlist"); 0164 edit->insertStringList(list); 0165 mainLayout->addWidget(edit); 0166 0167 // buttons 0168 QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel); 0169 mainLayout->addWidget(buttonBox); 0170 QPushButton *okButton = buttonBox->button(QDialogButtonBox::Ok); 0171 okButton->setDefault(true); 0172 okButton->setShortcut(Qt::CTRL | Qt::Key_Return); 0173 connect(buttonBox, SIGNAL(accepted()), &dialog, SLOT(accept())); 0174 connect(buttonBox, SIGNAL(rejected()), &dialog, SLOT(reject())); 0175 0176 if (dialog.exec() == QDialog::Accepted) { 0177 list = edit->items(); 0178 return true; 0179 } 0180 #endif 0181 return false; 0182 } 0183 0184 bool WidgetFactory::editRichText(QWidget *w, QString &text) const 0185 { 0186 RichTextDialog dlg(w, text); 0187 if (dlg.exec() == QDialog::Accepted) { 0188 text = dlg.text(); 0189 return true; 0190 } 0191 return false; 0192 } 0193 0194 #ifdef KEXI_LIST_FORM_WIDGET_SUPPORT 0195 void 0196 WidgetFactory::editListWidget(QListWidget *listwidget) const 0197 { 0198 EditListViewDialog dlg(static_cast<QWidget*>(listwidget)->topLevelWidget()); 0199 Q_UNUSED(dlg) 0200 //! @todo 0201 //dlg.exec(listview); 0202 } 0203 #endif 0204 0205 void WidgetFactory::changeProperty(Form *form, QWidget *widget, const char *name, const QVariant &value) 0206 { 0207 if (form->selectedWidget()) { // single selection 0208 form->propertySet()->changePropertyIfExists(name, value); 0209 widget->setProperty(name, value); 0210 } 0211 else { 0212 // If eg multiple labels are selected, 0213 // we only want to change the text of one of them (the one the user cliked on) 0214 if (widget) { 0215 widget->setProperty(name, value); 0216 } 0217 else { 0218 form->selectedWidgets()->first()->setProperty(name, value); 0219 } 0220 } 0221 } 0222 0223 bool 0224 WidgetFactory::isPropertyVisible(const QByteArray &classname, QWidget *w, 0225 const QByteArray &property, bool multiple, bool isTopLevel) 0226 { 0227 if (multiple) { 0228 return property == "font" || property == "paletteBackgroundColor" || property == "enabled" 0229 || property == "paletteForegroundColor" || property == "cursor" 0230 || property == "paletteBackgroundPixmap"; 0231 } 0232 0233 return isPropertyVisibleInternal(classname, w, property, isTopLevel); 0234 } 0235 0236 bool 0237 WidgetFactory::isPropertyVisibleInternal(const QByteArray &, QWidget *w, 0238 const QByteArray &property, bool isTopLevel) 0239 { 0240 Q_UNUSED(w); 0241 0242 #ifndef KEXI_FORM_CURSOR_PROPERTY_SUPPORT 0243 //! @todo temporary unless cursor works properly in the Designer 0244 if (property == "cursor") 0245 return false; 0246 #endif 0247 if (property == "acceptDrops" || property == "inputMethodHints") 0248 return false; 0249 0250 if (!isTopLevel 0251 && (property == "windowTitle" || property == "windowIcon" || property == "sizeIncrement" || property == "windowIconText")) { 0252 // don't show these properties for a non-toplevel widget 0253 return false; 0254 } 0255 return true; 0256 } 0257 0258 bool 0259 WidgetFactory::propertySetShouldBeReloadedAfterPropertyChange( 0260 const QByteArray& classname, QWidget *w, const QByteArray& property) 0261 { 0262 Q_UNUSED(classname) 0263 Q_UNUSED(w) 0264 Q_UNUSED(property) 0265 return false; 0266 } 0267 0268 void 0269 WidgetFactory::resizeEditor(QWidget *, QWidget *, const QByteArray&) 0270 { 0271 } 0272 0273 bool 0274 WidgetFactory::clearWidgetContent(const QByteArray &, QWidget *) 0275 { 0276 return false; 0277 } 0278 0279 bool WidgetFactory::changeInlineText(Form *form, QWidget *widget, 0280 const QString& text, QString *oldText) 0281 { 0282 if (oldText) { 0283 *oldText = widget->property("text").toString(); 0284 } 0285 changeProperty(form, widget, "text", text); 0286 return true; 0287 } 0288 0289 bool 0290 WidgetFactory::readSpecialProperty(const QByteArray &, QDomElement &, QWidget *, ObjectTreeItem *) 0291 { 0292 return false; 0293 } 0294 0295 bool 0296 WidgetFactory::saveSpecialProperty(const QByteArray &, const QString &, const QVariant&, QWidget *, QDomElement &, QDomDocument &) 0297 { 0298 return false; 0299 } 0300 0301 bool WidgetFactory::inheritsFactories() 0302 { 0303 foreach (WidgetInfo *winfo, d->classesByName) { 0304 if (!winfo->parentFactoryName().isEmpty()) 0305 return true; 0306 } 0307 return false; 0308 } 0309 0310 void WidgetFactory::setPropertyOptions(KPropertySet& set, const WidgetInfo& info, QWidget *w) 0311 { 0312 Q_UNUSED(set) 0313 Q_UNUSED(info) 0314 Q_UNUSED(w) 0315 //nothing 0316 } 0317 0318 ObjectTreeItem* WidgetFactory::selectableItem(ObjectTreeItem* item) 0319 { 0320 return item; 0321 } 0322 0323 void WidgetFactory::setInternalProperty(const QByteArray &classname, const QByteArray &property, const QVariant &value) 0324 { 0325 d->internalProp.insert(classname + ":" + property, value); 0326 } 0327 0328 QVariant WidgetFactory::internalProperty(const QByteArray &classname, const QByteArray &property) const 0329 { 0330 return d->internalProp.value(classname + ":" + property); 0331 } 0332 0333 QString WidgetFactory::propertyDescription(const char* name) const 0334 { 0335 return d->propDesc.value(name); 0336 } 0337 0338 QString WidgetFactory::valueDescription(const char* name) const 0339 { 0340 return d->propValDesc.value(name); 0341 } 0342 0343 WidgetInfo* WidgetFactory::widgetInfoForClassName(const char* classname) 0344 { 0345 return d->classesByName.value(classname); 0346 } 0347 0348 const QSet<QByteArray> *WidgetFactory::hiddenClasses() const 0349 { 0350 return d->hiddenClasses; 0351 } 0352 0353 WidgetLibrary* WidgetFactory::library() 0354 { 0355 return d->library; 0356 } 0357 0358 bool WidgetFactory::advancedPropertiesVisible() const 0359 { 0360 return d->advancedPropertiesVisible; 0361 } 0362 0363 void WidgetFactory::setLibrary(WidgetLibrary* library) 0364 { 0365 d->library = library; 0366 } 0367 0368 void WidgetFactory::setAdvancedPropertiesVisible(bool set) 0369 { 0370 d->advancedPropertiesVisible = set; 0371 } 0372 0373 void WidgetFactory::setPropertyDescription(const char* property, const QString &description) 0374 { 0375 d->propDesc.insert(property, description); 0376 } 0377 0378 void WidgetFactory::setValueDescription(const char *valueName, const QString &description) 0379 { 0380 d->propValDesc.insert(valueName, description); 0381 } 0382