00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "widgetfactory.h"
00023
00024 #include <qcursor.h>
00025 #include <qobjectlist.h>
00026 #include <qdict.h>
00027 #include <qmetaobject.h>
00028
00029 #include <kdebug.h>
00030 #include <klocale.h>
00031
00032 #include <ktextedit.h>
00033
00034 #include <klineedit.h>
00035
00036 #include <kdialogbase.h>
00037 #include <keditlistbox.h>
00038
00039 #include "richtextdialog.h"
00040 #include "editlistviewdialog.h"
00041 #include "resizehandle.h"
00042 #include "formmanager.h"
00043 #include "form.h"
00044 #include "container.h"
00045 #include "objecttree.h"
00046 #include "widgetlibrary.h"
00047 #include "utils.h"
00048 #include "widgetpropertyset.h"
00049 #include <koproperty/property.h>
00050
00051 using namespace KFormDesigner;
00052
00054
00055 WidgetInfo::WidgetInfo(WidgetFactory *f)
00056 : m_inheritedClass(0)
00057 , m_overriddenAlternateNames(0)
00058 , m_factory(f)
00059 , m_propertiesWithDisabledAutoSync(0)
00060 , m_customTypesForProperty(0)
00061 {
00062 }
00063
00064 WidgetInfo::WidgetInfo(WidgetFactory *f, const char* parentFactoryName,
00065 const char* inheritedClassName)
00066 : m_parentFactoryName( QCString("kformdesigner_")+parentFactoryName )
00067 , m_inheritedClassName(inheritedClassName)
00068 , m_inheritedClass(0)
00069 , m_overriddenAlternateNames(0)
00070 , m_factory(f)
00071 , m_propertiesWithDisabledAutoSync(0)
00072 , m_customTypesForProperty(0)
00073 {
00074 m_class = inheritedClassName;
00075 }
00076
00077 WidgetInfo::~WidgetInfo()
00078 {
00079 delete m_overriddenAlternateNames;
00080 delete m_propertiesWithDisabledAutoSync;
00081 delete m_customTypesForProperty;
00082 }
00083
00084 void WidgetInfo::addAlternateClassName(const QCString& alternateName, bool override)
00085 {
00086 m_alternateNames += alternateName;
00087 if (override) {
00088 if (!m_overriddenAlternateNames)
00089 m_overriddenAlternateNames = new QAsciiDict<char>(101);
00090 m_overriddenAlternateNames->insert(alternateName, (char*)1);
00091 }
00092 else {
00093 if (m_overriddenAlternateNames)
00094 m_overriddenAlternateNames->take(alternateName);
00095 }
00096 }
00097
00098 bool WidgetInfo::isOverriddenClassName(const QCString& alternateName) const
00099 {
00100 return m_overriddenAlternateNames && (m_overriddenAlternateNames->find(alternateName) != 0);
00101 }
00102
00103 void WidgetInfo::setAutoSyncForProperty(const char *propertyName, tristate flag)
00104 {
00105 if (!m_propertiesWithDisabledAutoSync) {
00106 if (~flag)
00107 return;
00108 m_propertiesWithDisabledAutoSync = new QAsciiDict<char>(101);
00109 }
00110
00111 if (~flag) {
00112 m_propertiesWithDisabledAutoSync->remove(propertyName);
00113 }
00114 else {
00115 m_propertiesWithDisabledAutoSync->insert(propertyName, flag ? (char*)1 : (char*)2);
00116 }
00117 }
00118
00119 tristate WidgetInfo::autoSyncForProperty(const char *propertyName) const
00120 {
00121 char* flag = m_propertiesWithDisabledAutoSync ? m_propertiesWithDisabledAutoSync->find(propertyName) : 0;
00122 if (!flag)
00123 return cancelled;
00124 return flag==(char*)1 ? true : false;
00125 }
00126
00127 void WidgetInfo::setCustomTypeForProperty(const char *propertyName, int type)
00128 {
00129 if (!propertyName || type==KoProperty::Auto)
00130 return;
00131 if (!m_customTypesForProperty) {
00132 m_customTypesForProperty = new QMap<QCString,int>();
00133 }
00134 m_customTypesForProperty->replace(propertyName, type);
00135 }
00136
00137 int WidgetInfo::customTypeForProperty(const char *propertyName) const
00138 {
00139 if (!m_customTypesForProperty || !m_customTypesForProperty->contains(propertyName))
00140 return KoProperty::Auto;
00141 return (*m_customTypesForProperty)[propertyName];
00142 }
00143
00144
00146
00147 WidgetFactory::WidgetFactory(QObject *parent, const char *name)
00148 : QObject(parent, (const char*)(QCString("kformdesigner_")+name))
00149 {
00150 m_showAdvancedProperties = true;
00151 m_classesByName.setAutoDelete(true);
00152 m_hiddenClasses = 0;
00153 }
00154
00155 WidgetFactory::~WidgetFactory()
00156 {
00157 delete m_hiddenClasses;
00158 }
00159
00160 void WidgetFactory::addClass(WidgetInfo *w)
00161 {
00162 WidgetInfo *oldw = m_classesByName[w->className()];
00163 if (oldw==w)
00164 return;
00165 if (oldw) {
00166 kdWarning() << "WidgetFactory::addClass(): class with name '" << w->className()
00167 << "' already exists for factory '" << name() << "'" << endl;
00168 return;
00169 }
00170 m_classesByName.insert( w->className(), w );
00171 }
00172
00173 void WidgetFactory::hideClass(const char *classname)
00174 {
00175 if (!m_hiddenClasses)
00176 m_hiddenClasses = new QAsciiDict<char>(101, false);
00177 m_hiddenClasses->insert(classname, (char*)1);
00178 }
00179
00180 void
00181 WidgetFactory::createEditor(const QCString &classname, const QString &text,
00182 QWidget *w, Container *container, QRect geometry,
00183 int align, bool useFrame, bool multiLine, BackgroundMode background)
00184 {
00185
00186 if (multiLine) {
00187 KTextEdit *textedit = new KTextEdit(text, QString::null, w->parentWidget());
00188 textedit->setTextFormat(Qt::PlainText);
00189 textedit->setAlignment(align);
00190 if (dynamic_cast<QTextEdit*>(w)) {
00191 textedit->setWordWrap(dynamic_cast<QTextEdit*>(w)->wordWrap());
00192 textedit->setWrapPolicy(dynamic_cast<QTextEdit*>(w)->wrapPolicy());
00193 }
00194 textedit->setPalette(w->palette());
00195 textedit->setFont(w->font());
00196 textedit->setResizePolicy(QScrollView::Manual);
00197 textedit->setGeometry(geometry);
00198 if(background == Qt::NoBackground)
00199 textedit->setBackgroundMode(w->backgroundMode());
00200 else
00201 textedit->setBackgroundMode(background);
00202
00203 textedit->setPaletteBackgroundColor(w->paletteBackgroundColor());
00204 for(int i =0; i <= textedit->paragraphs(); i++)
00205 textedit->setParagraphBackgroundColor(i, w->paletteBackgroundColor());
00206 textedit->selectAll(true);
00207 textedit->setColor(w->paletteForegroundColor());
00208 textedit->selectAll(false);
00209 textedit->moveCursor(QTextEdit::MoveEnd, false);
00210 textedit->setParagraphBackgroundColor(0, w->paletteBackgroundColor());
00211 textedit->setVScrollBarMode(QScrollView::AlwaysOff);
00212 textedit->setHScrollBarMode(QScrollView::AlwaysOff);
00213 textedit->installEventFilter(this);
00214 textedit->setFrameShape(useFrame ? QFrame::LineEditPanel : QFrame::NoFrame);
00215 textedit->setMargin(2);
00216 textedit->show();
00217 textedit->setFocus();
00218 textedit->selectAll();
00219 setEditor(w, textedit);
00220
00221 connect(textedit, SIGNAL(textChanged()), this, SLOT(slotTextChanged()));
00222 connect(w, SIGNAL(destroyed()), this, SLOT(widgetDestroyed()));
00223 connect(textedit, SIGNAL(destroyed()), this, SLOT(editorDeleted()));
00224
00225 }
00226 else {
00227 KLineEdit *editor = new KLineEdit(text, w->parentWidget());
00228 editor->setAlignment(align);
00229 editor->setPalette(w->palette());
00230 editor->setFont(w->font());
00231 editor->setGeometry(geometry);
00232 if(background == Qt::NoBackground)
00233 editor->setBackgroundMode(w->backgroundMode());
00234 else
00235 editor->setBackgroundMode(background);
00236 editor->installEventFilter(this);
00237 editor->setFrame(useFrame);
00238 editor->setMargin(2);
00239 editor->show();
00240 editor->setFocus();
00241 editor->selectAll();
00242 connect(editor, SIGNAL(textChanged(const QString&)), this, SLOT(changeTextInternal(const QString&)));
00243 connect(w, SIGNAL(destroyed()), this, SLOT(widgetDestroyed()));
00244 connect(editor, SIGNAL(destroyed()), this, SLOT(editorDeleted()));
00245
00246 setEditor(w, editor);
00247
00248 }
00249
00250 if (-1!=m_editor->metaObject()->findProperty("margin", true) && -1!=w->metaObject()->findProperty("margin", true))
00251 m_editor->setProperty("margin", w->property("margin"));
00252
00253
00254 m_handles = container->form()->resizeHandlesForWidget(w);
00255 if (m_handles) {
00256 m_handles->setEditingMode(true);
00257 m_handles->raise();
00258 }
00259
00260 ObjectTreeItem *tree = container->form()->objectTree()->lookup(w->name());
00261 if(!tree)
00262 return;
00263 tree->eventEater()->setContainer(this);
00264
00265
00266 setWidget(w, container);
00267 m_editedWidgetClass = classname;
00268 m_firstText = text;
00269
00270
00271 changeTextInternal(text);
00272 }
00273
00274 void
00275 WidgetFactory::disableFilter(QWidget *w, Container *container)
00276 {
00277 ObjectTreeItem *tree = container->form()->objectTree()->lookup(w->name());
00278 if(!tree)
00279 return;
00280 tree->eventEater()->setContainer(this);
00281
00282 w->setFocus();
00283
00284 m_handles = container->form()->resizeHandlesForWidget(w);
00285 if (m_handles) {
00286 m_handles->setEditingMode(true);
00287 m_handles->raise();
00288 }
00289
00290
00291 setWidget(w, container);
00292
00293 setEditor(w, 0);
00294
00295
00296
00297 if(!tree->isEnabled()) {
00298 QPalette p = w->palette();
00299 QColorGroup cg = p.active();
00300 p.setActive(p.disabled());
00301 p.setDisabled(cg);
00302 w->setPalette(p);
00303 }
00304
00305 connect(w, SIGNAL(destroyed()), this, SLOT(widgetDestroyed()));
00306 }
00307
00308 bool
00309 WidgetFactory::editList(QWidget *w, QStringList &list)
00310 {
00311 KDialogBase dialog(w->topLevelWidget(), "stringlist_dialog", true, i18n("Edit List of Items"),
00312 KDialogBase::Ok|KDialogBase::Cancel, KDialogBase::Ok, false);
00313
00314 KEditListBox *edit = new KEditListBox(i18n("Contents of %1").arg(w->name()), &dialog, "editlist");
00315 dialog.setMainWidget(edit);
00316 edit->insertStringList(list);
00317
00318
00319 if(dialog.exec() == QDialog::Accepted)
00320 {
00321 list = edit->items();
00322 return true;
00323 }
00324 return false;
00325 }
00326
00327 bool
00328 WidgetFactory::editRichText(QWidget *w, QString &text)
00329 {
00330 RichTextDialog dlg(w, text);
00331 if(dlg.exec()== QDialog::Accepted)
00332 {
00333 text = dlg.text();
00334 return true;
00335 }
00336 return false;
00337 }
00338
00339 void
00340 WidgetFactory::editListView(QListView *listview)
00341 {
00342 EditListViewDialog dlg(((QWidget*)listview)->topLevelWidget());
00343
00344 }
00345
00346 bool
00347 WidgetFactory::eventFilter(QObject *obj, QEvent *ev)
00348 {
00349 if( ((ev->type() == QEvent::Resize) || (ev->type() == QEvent::Move) ) && (obj == m_widget) && editor(m_widget)) {
00350
00351 QWidget *ed = editor(m_widget);
00352 resizeEditor(ed, m_widget, m_widget->className());
00353 }
00354 else if((ev->type() == QEvent::Paint) && (obj == m_widget) && editor(m_widget)) {
00355
00356 return m_container->eventFilter(obj, ev);
00357 }
00358 else if((ev->type() == QEvent::MouseButtonPress) && (obj == m_widget) && editor(m_widget)) {
00359
00360 Container *cont = m_container;
00361 resetEditor();
00362 return cont->eventFilter(obj, ev);
00363 }
00364
00365 if(ev->type() == QEvent::FocusOut)
00366 {
00367 QWidget *w = editor(m_widget);
00368 if (!w)
00369 w = (QWidget *)m_widget;
00370 if(obj != (QObject *)w)
00371 return false;
00372
00373 QWidget *focus = w->topLevelWidget()->focusWidget();
00374 if(focus && w != focus && !w->child(focus->name(), focus->className()))
00375 resetEditor();
00376 }
00377 else if(ev->type() == QEvent::KeyPress)
00378 {
00379 QWidget *w = editor(m_widget);
00380 if (!w)
00381 w = (QWidget *)m_widget;
00382 if(obj != (QObject *)w)
00383 return false;
00384
00385 QKeyEvent *e = static_cast<QKeyEvent*>(ev);
00386 if(((e->key() == Qt::Key_Return) || (e->key() == Qt::Key_Enter)) && (e->state() != AltButton))
00387 resetEditor();
00388 if(e->key() == Qt::Key_Escape)
00389 {
00390 setEditorText(m_firstText);
00391
00392 resetEditor();
00393 }
00394 }
00395 else if(ev->type() == QEvent::ContextMenu) {
00396 QWidget *w = editor(m_widget);
00397 if (!w)
00398 w = (QWidget *)m_widget;
00399 if(obj != (QObject *)w)
00400 return false;
00401
00402 return true;
00403 }
00404
00405
00406
00407 return false;
00408 }
00409
00410 void
00411 WidgetFactory::resetEditor()
00412 {
00413 if (m_container)
00414 m_container->stopInlineEditing();
00415
00416 QWidget *ed = editor(m_widget);
00417 if(m_widget)
00418 {
00419 ObjectTreeItem *tree = m_container ? m_container->form()->objectTree()->lookup(m_widget->name()) : 0;
00420 if(!tree)
00421 {
00422 kdDebug() << "WidgetFactory::resetEditor() : error cannot found a tree item " << endl;
00423 return;
00424 }
00425 tree->eventEater()->setContainer(m_container);
00426 if(m_widget) {
00427 setRecursiveCursor(m_widget, m_container->form());
00428 if (m_widget->inherits("QLineEdit") || m_widget->inherits("QTextEdit")) {
00429 m_widget->unsetCursor();
00430 m_widget->setCursor(Qt::ArrowCursor);
00431 }
00432 }
00433
00434
00435 if(!ed && !tree->isEnabled()) {
00436 QPalette p = m_widget->palette();
00437 QColorGroup cg = p.active();
00438 p.setActive(p.disabled());
00439 p.setDisabled(cg);
00440 m_widget->setPalette(p);
00441 }
00442 }
00443 if(ed)
00444 {
00445 changeTextInternal(editorText());
00446 disconnect(ed, 0, this, 0);
00447 ed->deleteLater();
00448 }
00449
00450 if(m_widget)
00451 {
00452 disconnect(m_widget, 0, this, 0);
00453 m_widget->repaint();
00454 }
00455
00456
00457 if (m_handles) {
00458 m_handles->setEditingMode(false);
00459 }
00460 setEditor(m_widget, 0);
00461
00462 setWidget(0, 0);
00463
00464 m_handles = 0;
00465
00466 }
00467
00468 void
00469 WidgetFactory::widgetDestroyed()
00470 {
00471 if(m_editor)
00472 {
00473 m_editor->deleteLater();
00474 m_editor = 0;
00475 }
00476
00477
00478 if (m_handles) {
00479 m_handles->setEditingMode(false);
00480
00481 }
00482 m_widget = 0;
00483 m_handles = 0;
00484 m_container = 0;
00485 }
00486
00487 void
00488 WidgetFactory::editorDeleted()
00489 {
00490
00491 if (m_handles) {
00492 m_handles->setEditingMode(false);
00493 }
00494 setEditor(m_widget, 0);
00495 setWidget(0, 0);
00496
00497 m_handles = 0;
00498
00499 }
00500
00501 void
00502 WidgetFactory::changeProperty(const char *name, const QVariant &value, Form *form)
00503
00504 {
00505
00506
00507 if(form->selectedWidgets()->count() > 1)
00508 {
00509 if(m_widget)
00510 m_widget->setProperty(name, value);
00511 else
00512 form->selectedWidgets()->first()->setProperty(name, value);
00513 }
00514 else
00515 {
00516 WidgetPropertySet *set = KFormDesigner::FormManager::self()->propertySet();
00517 if(set->contains(name))
00518 (*set)[name] = value;
00519 }
00520 }
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537 bool
00538 WidgetFactory::isPropertyVisible(const QCString &classname, QWidget *w,
00539 const QCString &property, bool multiple, bool isTopLevel)
00540 {
00541 if (multiple)
00542 {
00543 return property=="font" || property=="paletteBackgroundColor" || property=="enabled"
00544 || property=="paletteForegroundColor" || property=="cursor" || property=="paletteBackgroundPixmap";
00545 }
00546
00547
00548
00549
00550
00551
00552 return isPropertyVisibleInternal(classname, w, property, isTopLevel);
00553
00554 }
00555
00556 bool
00557 WidgetFactory::isPropertyVisibleInternal(const QCString &, QWidget *w,
00558 const QCString &property, bool isTopLevel)
00559 {
00560 Q_UNUSED( w );
00561
00562 #ifdef KEXI_NO_CURSOR_PROPERTY
00564 if (property=="cursor")
00565 return false;
00566 #endif
00567
00568 if (!isTopLevel
00569 && (property=="caption" || property=="icon" || property=="sizeIncrement" || property=="iconText")) {
00570
00571 return false;
00572 }
00573 return true;
00574 }
00575
00576 void
00577 WidgetFactory::resizeEditor(QWidget *, QWidget *, const QCString&)
00578 {
00579 }
00580
00581 void
00582 WidgetFactory::slotTextChanged()
00583 {
00584 changeTextInternal(editorText());
00585 }
00586
00587 bool
00588 WidgetFactory::clearWidgetContent(const QCString &, QWidget *)
00589 {
00590 return false;
00591 }
00592
00593 void
00594 WidgetFactory::changeTextInternal(const QString& text)
00595 {
00596 if (changeText( text ))
00597 return;
00598
00599 if (!m_editedWidgetClass.isEmpty()) {
00600 WidgetInfo *wi = m_classesByName[ m_editedWidgetClass ];
00601 if (wi && wi->inheritedClass()) {
00602
00603 wi->inheritedClass()->factory()->changeText( text );
00604 }
00605 }
00606 }
00607
00608 bool
00609 WidgetFactory::changeText(const QString& text)
00610 {
00611 changeProperty( "text", text, m_container->form() );
00612 return true;
00613 }
00614
00615 bool
00616 WidgetFactory::readSpecialProperty(const QCString &, QDomElement &, QWidget *, ObjectTreeItem *)
00617 {
00618 return false;
00619 }
00620
00621 bool
00622 WidgetFactory::saveSpecialProperty(const QCString &, const QString &, const QVariant&, QWidget *, QDomElement &, QDomDocument &)
00623 {
00624 return false;
00625 }
00626
00627 bool WidgetFactory::inheritsFactories()
00628 {
00629 for (QAsciiDictIterator<WidgetInfo> it(m_classesByName); it.current(); ++it) {
00630 if (!it.current()->parentFactoryName().isEmpty())
00631 return true;
00632 }
00633 return false;
00634 }
00635
00636 QString WidgetFactory::editorText() const {
00637 QWidget *ed = editor(m_widget);
00638 return dynamic_cast<KTextEdit*>(ed) ? dynamic_cast<KTextEdit*>(ed)->text() : dynamic_cast<KLineEdit*>(ed)->text();
00639 }
00640
00641 void WidgetFactory::setEditorText(const QString& text) {
00642 QWidget *ed = editor(m_widget);
00643 if (dynamic_cast<KTextEdit*>(ed))
00644 dynamic_cast<KTextEdit*>(ed)->setText(text);
00645 else
00646 dynamic_cast<KLineEdit*>(ed)->setText(text);
00647 }
00648
00649 void WidgetFactory::setEditor(QWidget *widget, QWidget *editor)
00650 {
00651 if (!widget)
00652 return;
00653 WidgetInfo *winfo = m_classesByName[widget->className()];
00654 if (!winfo || winfo->parentFactoryName().isEmpty()) {
00655 m_editor = editor;
00656 }
00657 else {
00658 WidgetFactory *f = m_library->factory(winfo->parentFactoryName());
00659 if (f!=this)
00660 f->setEditor(widget, editor);
00661 m_editor = editor;
00662 }
00663 }
00664
00665 QWidget *WidgetFactory::editor(QWidget *widget) const
00666 {
00667 if (!widget)
00668 return 0;
00669 WidgetInfo *winfo = m_classesByName[widget->className()];
00670 if (!winfo || winfo->parentFactoryName().isEmpty()) {
00671 return m_editor;
00672 }
00673 else {
00674 WidgetFactory *f = m_library->factoryForClassName(widget->className());
00675 if (f!=this)
00676 return f->editor(widget);
00677 return m_editor;
00678 }
00679 }
00680
00681 void WidgetFactory::setWidget(QWidget *widget, Container* container)
00682 {
00683 WidgetInfo *winfo = widget ? m_classesByName[widget->className()] : 0;
00684 if (winfo && !winfo->parentFactoryName().isEmpty()) {
00685 WidgetFactory *f = m_library->factory(winfo->parentFactoryName());
00686 if (f!=this)
00687 f->setWidget(widget, container);
00688 }
00689 m_widget = widget;
00690 m_container = container;
00691 }
00692
00693 QWidget *WidgetFactory::widget() const
00694 {
00695 return m_widget;
00696 }
00697
00698 void WidgetFactory::setInternalProperty(const QCString& classname, const QCString& property,
00699 const QString& value)
00700 {
00701 m_internalProp[classname+":"+property]=value;
00702 }
00703
00704 void WidgetFactory::setPropertyOptions( WidgetPropertySet& , const WidgetInfo& , QWidget * )
00705 {
00706
00707 }
00708
00709 #include "widgetfactory.moc"