File indexing completed on 2024-05-19 12:54:38
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 if (property == "objectName") { // name is available in the KexiObjectInfoWidget 0243 return false; 0244 } 0245 #ifndef KEXI_FORM_CURSOR_PROPERTY_SUPPORT 0246 //! @todo temporary unless cursor works properly in the Designer 0247 if (property == "cursor") 0248 return false; 0249 #endif 0250 if (property == "acceptDrops" || property == "inputMethodHints") 0251 return false; 0252 0253 if (!isTopLevel 0254 && (property == "windowTitle" || property == "windowIcon" || property == "sizeIncrement" || property == "windowIconText")) { 0255 // don't show these properties for a non-toplevel widget 0256 return false; 0257 } 0258 return true; 0259 } 0260 0261 bool 0262 WidgetFactory::propertySetShouldBeReloadedAfterPropertyChange( 0263 const QByteArray& classname, QWidget *w, const QByteArray& property) 0264 { 0265 Q_UNUSED(classname) 0266 Q_UNUSED(w) 0267 Q_UNUSED(property) 0268 return false; 0269 } 0270 0271 void 0272 WidgetFactory::resizeEditor(QWidget *, QWidget *, const QByteArray&) 0273 { 0274 } 0275 0276 bool 0277 WidgetFactory::clearWidgetContent(const QByteArray &, QWidget *) 0278 { 0279 return false; 0280 } 0281 0282 bool WidgetFactory::changeInlineText(Form *form, QWidget *widget, 0283 const QString& text, QString *oldText) 0284 { 0285 if (oldText) { 0286 *oldText = widget->property("text").toString(); 0287 } 0288 changeProperty(form, widget, "text", text); 0289 return true; 0290 } 0291 0292 bool 0293 WidgetFactory::readSpecialProperty(const QByteArray &, QDomElement &, QWidget *, ObjectTreeItem *) 0294 { 0295 return false; 0296 } 0297 0298 bool 0299 WidgetFactory::saveSpecialProperty(const QByteArray &, const QString &, const QVariant&, QWidget *, QDomElement &, QDomDocument &) 0300 { 0301 return false; 0302 } 0303 0304 bool WidgetFactory::inheritsFactories() 0305 { 0306 foreach (WidgetInfo *winfo, d->classesByName) { 0307 if (!winfo->parentFactoryName().isEmpty()) 0308 return true; 0309 } 0310 return false; 0311 } 0312 0313 void WidgetFactory::setPropertyOptions(KPropertySet& set, const WidgetInfo& info, QWidget *w) 0314 { 0315 Q_UNUSED(set) 0316 Q_UNUSED(info) 0317 Q_UNUSED(w) 0318 //nothing 0319 } 0320 0321 ObjectTreeItem* WidgetFactory::selectableItem(ObjectTreeItem* item) 0322 { 0323 return item; 0324 } 0325 0326 void WidgetFactory::setInternalProperty(const QByteArray &classname, const QByteArray &property, const QVariant &value) 0327 { 0328 d->internalProp.insert(classname + ":" + property, value); 0329 } 0330 0331 QVariant WidgetFactory::internalProperty(const QByteArray &classname, const QByteArray &property) const 0332 { 0333 return d->internalProp.value(classname + ":" + property); 0334 } 0335 0336 QString WidgetFactory::propertyDescription(const char* name) const 0337 { 0338 return d->propDesc.value(name); 0339 } 0340 0341 QString WidgetFactory::valueDescription(const char* name) const 0342 { 0343 return d->propValDesc.value(name); 0344 } 0345 0346 WidgetInfo* WidgetFactory::widgetInfoForClassName(const char* classname) 0347 { 0348 return d->classesByName.value(classname); 0349 } 0350 0351 const QSet<QByteArray> *WidgetFactory::hiddenClasses() const 0352 { 0353 return d->hiddenClasses; 0354 } 0355 0356 WidgetLibrary* WidgetFactory::library() 0357 { 0358 return d->library; 0359 } 0360 0361 bool WidgetFactory::advancedPropertiesVisible() const 0362 { 0363 return d->advancedPropertiesVisible; 0364 } 0365 0366 void WidgetFactory::setLibrary(WidgetLibrary* library) 0367 { 0368 d->library = library; 0369 } 0370 0371 void WidgetFactory::setAdvancedPropertiesVisible(bool set) 0372 { 0373 d->advancedPropertiesVisible = set; 0374 } 0375 0376 void WidgetFactory::setPropertyDescription(const char* property, const QString &description) 0377 { 0378 d->propDesc.insert(property, description); 0379 } 0380 0381 void WidgetFactory::setValueDescription(const char *valueName, const QString &description) 0382 { 0383 d->propValDesc.insert(valueName, description); 0384 } 0385