00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "editor.h"
00023 #include "editoritem.h"
00024 #include "set.h"
00025 #include "factory.h"
00026 #include "property.h"
00027 #include "widget.h"
00028
00029 #include <qpushbutton.h>
00030 #include <qlayout.h>
00031 #include <qmap.h>
00032 #include <qguardedptr.h>
00033 #include <qheader.h>
00034 #include <qasciidict.h>
00035 #include <qtooltip.h>
00036 #include <qapplication.h>
00037 #include <qeventloop.h>
00038 #include <qtimer.h>
00039
00040 #ifdef QT_ONLY
00041 #else
00042 #include <kdebug.h>
00043 #include <kiconloader.h>
00044 #include <klocale.h>
00045 #include <kdeversion.h>
00046 #include <kapplication.h>
00047 #endif
00048
00049 namespace KoProperty {
00050
00052 static bool kofficeAppDirAdded = false;
00053
00056 inline bool hasParent(QObject* par, QObject* o)
00057 {
00058 if (!o || !par)
00059 return false;
00060 while (o && o != par)
00061 o = o->parent();
00062 return o == par;
00063 }
00064
00065 class EditorPrivate
00066 {
00067 public:
00068 EditorPrivate(Editor *editor)
00069 : itemDict(101, false), justClickedItem(false)
00070 {
00071 currentItem = 0;
00072 undoButton = 0;
00073 topItem = 0;
00074 if (!kofficeAppDirAdded) {
00075 kofficeAppDirAdded = true;
00076 KGlobal::iconLoader()->addAppDir("koffice");
00077 }
00078 previouslyCollapsedGroupItem = 0;
00079 childFormPreviouslyCollapsedGroupItem = 0;
00080 slotPropertyChanged_enabled = true;
00081 QObject::connect(&changeSetLaterTimer, SIGNAL(timeout()),
00082 editor, SLOT(changeSetLater()));
00083 }
00084 ~EditorPrivate()
00085 {
00086 }
00087
00088 QGuardedPtr<Set> set;
00090 QMap<Property*, Widget* > widgetCache;
00091 QGuardedPtr<Widget> currentWidget;
00092 EditorItem *currentItem;
00093 EditorItem *topItem;
00094 QPushButton *undoButton;
00095 EditorItem::Dict itemDict;
00096
00097 int baseRowHeight;
00098 bool sync : 1;
00099 bool insideSlotValueChanged : 1;
00100
00102 QTimer changeSetLaterTimer;
00103 bool setListLater_set : 1;
00104 bool preservePrevSelection_preservePrevSelection : 1;
00105
00107 bool justClickedItem : 1;
00109 bool slotPropertyChanged_enabled : 1;
00111 Set* setListLater_list;
00113 EditorItem *itemToSelectLater;
00114
00115 QListViewItem *previouslyCollapsedGroupItem;
00116 QListViewItem *childFormPreviouslyCollapsedGroupItem;
00117 };
00118 }
00119
00120 using namespace KoProperty;
00121
00122 Editor::Editor(QWidget *parent, bool autoSync, const char *name)
00123 : KListView(parent, name)
00124 {
00125 d = new EditorPrivate(this);
00126 d->itemDict.setAutoDelete(false);
00127
00128 d->set = 0;
00129 d->topItem = 0;
00130 d->currentItem = 0;
00131 d->sync = autoSync;
00132 d->insideSlotValueChanged = false;
00133 d->setListLater_set = false;
00134 d->preservePrevSelection_preservePrevSelection = false;
00135 d->setListLater_list = 0;
00136
00137 d->undoButton = new QPushButton(viewport());
00138 d->undoButton->setFocusPolicy(QWidget::NoFocus);
00139 setFocusPolicy(QWidget::ClickFocus);
00140 d->undoButton->setMinimumSize(QSize(5,5));
00141 d->undoButton->setPixmap(SmallIcon("undo"));
00142 QToolTip::add(d->undoButton, i18n("Undo changes"));
00143 d->undoButton->hide();
00144 connect(d->undoButton, SIGNAL(clicked()), this, SLOT(undo()));
00145
00146 installEventFilter(this);
00147 viewport()->installEventFilter(this);
00148
00149 addColumn(i18n("Name"));
00150 addColumn(i18n("Value"));
00151 setAllColumnsShowFocus(true);
00152 setColumnWidthMode(0, QListView::Maximum);
00153 setFullWidth(true);
00154 setShowSortIndicator(false);
00155 #if KDE_IS_VERSION(3,3,9)
00156 setShadeSortColumn(false);
00157 #endif
00158 setTooltipColumn(0);
00159 setSorting(0);
00160 setItemMargin(KPROPEDITOR_ITEM_MARGIN);
00161 header()->setMovingEnabled( false );
00162 setTreeStepSize(16 + 2 + 1);
00163
00164 updateFont();
00165
00166
00167 connect(this, SIGNAL(selectionChanged(QListViewItem *)), this, SLOT(slotClicked(QListViewItem *)));
00168 connect(this, SIGNAL(currentChanged(QListViewItem *)), this, SLOT(slotCurrentChanged(QListViewItem *)));
00169 connect(this, SIGNAL(expanded(QListViewItem *)), this, SLOT(slotExpanded(QListViewItem *)));
00170 connect(this, SIGNAL(collapsed(QListViewItem *)), this, SLOT(slotCollapsed(QListViewItem *)));
00171 connect(header(), SIGNAL(sizeChange(int, int, int)), this, SLOT(slotColumnSizeChanged(int, int, int)));
00172 connect(header(), SIGNAL(clicked(int)), this, SLOT(updateEditorGeometry()));
00173 connect(header(), SIGNAL(sectionHandleDoubleClicked (int)), this, SLOT(slotColumnSizeChanged(int)));
00174 }
00175
00176 Editor::~Editor()
00177 {
00178 clearWidgetCache();
00179 delete d;
00180 }
00181
00182 void
00183 Editor::fill()
00184 {
00185 setUpdatesEnabled(false);
00186 qApp->eventLoop()->processEvents(QEventLoop::AllEvents);
00187 hideEditor();
00188 KListView::clear();
00189 d->itemDict.clear();
00190 clearWidgetCache();
00191 if(!d->set) {
00192 d->topItem = 0;
00193 setUpdatesEnabled(true);
00194 triggerUpdate();
00195 return;
00196 }
00197
00198 d->topItem = new EditorDummyItem(this);
00199
00200
00201 StringListMap map = d->set->groups();
00202
00203 if(map.count() == 1) {
00204
00205
00206 QValueList<QCString> props = map.begin().data();
00207 QValueList<QCString>::ConstIterator it = props.constBegin();
00208 for( ; it != props.constEnd(); ++it)
00209 addItem(*it, d->topItem);
00210
00211 } else {
00212 StringListMap::ConstIterator it = map.constBegin();
00213 for( ; it != map.constEnd(); ++it) {
00214 EditorGroupItem *groupItem = 0;
00215 if(!it.key().isEmpty() && !it.data().isEmpty() && map.count() > 1)
00216 groupItem = new EditorGroupItem(d->topItem, d->set->groupDescription(it.key()) );
00217
00218 QValueList<QCString>::ConstIterator it2 = it.data().constBegin();
00219 for( ; it2 != it.data().constEnd(); ++it2)
00220 addItem(*it2, groupItem);
00221 }
00222
00223 }
00224
00225
00226
00227 if (firstChild())
00228 {
00229 setCurrentItem(firstChild());
00230 setSelected(firstChild(), true);
00231 slotClicked(firstChild());
00232 }
00233 setUpdatesEnabled(true);
00234
00235 triggerUpdate();
00236 }
00237
00238 void
00239 Editor::addItem(const QCString &name, EditorItem *parent)
00240 {
00241 if(!d->set || !d->set->contains(name))
00242 return;
00243
00244 Property *property = &(d->set->property(name));
00245 if(!property || !property->isVisible()) {
00246
00247 return;
00248 }
00249 QListViewItem *last = parent ? parent->firstChild() : d->topItem->firstChild();
00250 while(last && last->nextSibling())
00251 last = last->nextSibling();
00252
00253 EditorItem *item=0;
00254 if(parent)
00255 item = new EditorItem(this, parent, property, last);
00256 else
00257 item = new EditorItem(this, d->topItem, property, last);
00258 d->itemDict.insert(name, item);
00259
00260
00261 item->setOpen(true);
00262 if(!property->children())
00263 return;
00264
00265 last = 0;
00266 QValueList<Property*>::ConstIterator endIt = property->children()->constEnd();
00267 for(QValueList<Property*>::ConstIterator it = property->children()->constBegin(); it != endIt; ++it) {
00269 if( *it && (*it)->isVisible() )
00270 last = new EditorItem(this, item, *it, last);
00271 }
00272 }
00273
00274 void
00275 Editor::changeSet(Set *set, bool preservePrevSelection)
00276 {
00277 if (d->insideSlotValueChanged) {
00278
00279
00280
00281 d->setListLater_list = set;
00282 d->preservePrevSelection_preservePrevSelection = preservePrevSelection;
00283 qApp->eventLoop()->processEvents(QEventLoop::AllEvents);
00284 if (!d->setListLater_set) {
00285 d->setListLater_set = true;
00286 d->changeSetLaterTimer.start(10, true);
00287 }
00288 return;
00289 }
00290
00291 if (d->set) {
00292 slotWidgetAcceptInput(d->currentWidget);
00293
00294 if (d->currentItem)
00295 d->set->setPrevSelection( d->currentItem->property()->name() );
00296 d->set->disconnect(this);
00297 }
00298
00299 QCString selectedPropertyName1, selectedPropertyName2;
00300 if (preservePrevSelection) {
00301
00302
00303 if(set)
00304 selectedPropertyName1 = set->prevSelection();
00305
00306 if(d->set)
00307 selectedPropertyName2 = d->set->prevSelection();
00308 }
00309
00310 d->set = set;
00311 if (d->set) {
00312
00313 connect(d->set, SIGNAL(propertyChanged(KoProperty::Set&, KoProperty::Property&, const QVariant&)),
00314 this, SLOT(slotPropertyChanged(KoProperty::Set&, KoProperty::Property&)));
00315 connect(d->set, SIGNAL(propertyReset(KoProperty::Set&, KoProperty::Property&)),
00316 this, SLOT(slotPropertyReset(KoProperty::Set&, KoProperty::Property&)));
00317 connect(d->set,SIGNAL(aboutToBeCleared()), this, SLOT(slotSetWillBeCleared()));
00318 connect(d->set,SIGNAL(aboutToBeDeleted()), this, SLOT(slotSetWillBeDeleted()));
00319 }
00320
00321 fill();
00322 if (d->set) {
00323
00324 EditorItem * item = 0;
00325 if (!selectedPropertyName2.isEmpty())
00326 item = d->itemDict[selectedPropertyName2];
00327 if (!item && !selectedPropertyName1.isEmpty())
00328 item = d->itemDict[selectedPropertyName1];
00329
00330 if (item) {
00331 d->itemToSelectLater = item;
00332 QTimer::singleShot(10, this, SLOT(selectItemLater()));
00333
00334
00335
00336
00337 }
00338 }
00339
00340 emit propertySetChanged(d->set);
00341 }
00342
00344 void Editor::selectItemLater()
00345 {
00346 if (!d->itemToSelectLater)
00347 return;
00348 EditorItem *item = d->itemToSelectLater;
00349 d->itemToSelectLater = 0;
00350 setSelected(item, true);
00351 ensureItemVisible(item);
00352 }
00353
00355 void
00356 Editor::changeSetLater()
00357 {
00358 qApp->eventLoop()->processEvents(QEventLoop::AllEvents);
00359 if (kapp->hasPendingEvents())
00360 return;
00361 d->setListLater_set = false;
00362 if (!d->setListLater_list)
00363 return;
00364
00365 bool b = d->insideSlotValueChanged;
00366 d->insideSlotValueChanged = false;
00367 changeSet(d->setListLater_list, d->preservePrevSelection_preservePrevSelection);
00368 d->insideSlotValueChanged = b;
00369 }
00370
00371 void
00372 Editor::clear(bool editorOnly)
00373 {
00374 hideEditor();
00375 d->itemToSelectLater = 0;
00376
00377 if(!editorOnly) {
00378 qApp->eventLoop()->processEvents(QEventLoop::AllEvents);
00379 clearWidgetCache();
00380 KListView::clear();
00381 d->itemDict.clear();
00382 d->topItem = 0;
00383 if(d->set)
00384 d->set->disconnect(this);
00385 }
00386 }
00387
00388 void
00389 Editor::undo()
00390 {
00391 if(!d->currentWidget || !d->currentItem || (d->set && d->set->isReadOnly()) || (d->currentWidget && d->currentWidget->isReadOnly()))
00392 return;
00393
00394 int propertySync = d->currentWidget->property()->autoSync();
00395 bool sync = (propertySync != 0 && propertySync != 1) ?
00396 d->sync : (propertySync!=0);
00397
00398 if(sync)
00399 d->currentItem->property()->resetValue();
00400 if (d->currentWidget && d->currentItem) {
00401 d->currentWidget->setValue( d->currentItem->property()->value());
00402 repaintItem(d->currentItem);
00403 }
00404 }
00405
00406 void
00407 Editor::slotPropertyChanged(Set& set, Property& property)
00408 {
00409 if (!d->slotPropertyChanged_enabled)
00410 return;
00411 if(&set != d->set)
00412 return;
00413
00414 if (d->currentItem && d->currentItem->property() == &property) {
00415 d->currentWidget->setValue(property.value(), false);
00416 for(QListViewItem *item = d->currentItem->firstChild(); item; item = item->nextSibling())
00417 repaintItem(item);
00418 }
00419 else {
00420
00421 EditorItem *item = d->itemDict[property.name()];
00422 if(!item && property.parent())
00423 item = d->itemDict[property.parent()->name()];
00424 if (item) {
00425 repaintItem(item);
00426 for(QListViewItem *it = item->firstChild(); it; it = it->nextSibling())
00427 repaintItem(it);
00428 }
00429 }
00430
00432 #if 0
00433 if (property.parent() && property.parent()->type()==Rect) {
00434 const int delta = property.value().toInt()-previousValue.toInt();
00435 if (property.type()==Rect_X) {
00436 property.parent()->child("width")->setValue(delta, false);
00437 }
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451 }
00452 #endif
00453 showUndoButton( property.isModified() );
00454 }
00455
00456 void
00457 Editor::slotPropertyReset(Set& set, Property& property)
00458 {
00459 if(&set != d->set)
00460 return;
00461
00462 if (d->currentItem && d->currentItem->property() == &property) {
00463 d->currentWidget->setValue(property.value(), false);
00464 for(QListViewItem *item = d->currentItem->firstChild(); item; item = item->nextSibling())
00465 repaintItem(item);
00466 }
00467 else {
00468 EditorItem *item = d->itemDict[property.name()];
00469
00470 if(!item && property.parent())
00471 item = d->itemDict[property.parent()->name()];
00472 repaintItem(item);
00473 for(QListViewItem *it = item->firstChild(); it; it = it->nextSibling())
00474 repaintItem(it);
00475 }
00476
00477 showUndoButton( false );
00478 }
00479
00480 void
00481 Editor::slotWidgetValueChanged(Widget *widget)
00482 {
00483 if(!widget || !d->set || (d->set && d->set->isReadOnly()) || (widget && widget->isReadOnly()))
00484 return;
00485
00486 d->insideSlotValueChanged = true;
00487
00488 QVariant value = widget->value();
00489 int propertySync = widget->property()->autoSync();
00490 bool sync = (propertySync != 0 && propertySync != 1) ?
00491 d->sync : (propertySync!=0);
00492
00493 if(sync) {
00494 d->slotPropertyChanged_enabled = false;
00495 widget->property()->setValue(value);
00496 showUndoButton( widget->property()->isModified() );
00497 d->slotPropertyChanged_enabled = true;
00498 }
00499
00500 d->insideSlotValueChanged = false;
00501 }
00502
00503 void
00504 Editor::acceptInput()
00505 {
00506 slotWidgetAcceptInput(d->currentWidget);
00507 }
00508
00509 void
00510 Editor::slotWidgetAcceptInput(Widget *widget)
00511 {
00512 if(!widget || !d->set || !widget->property() || (d->set && d->set->isReadOnly()) || (widget && widget->isReadOnly()))
00513 return;
00514
00515 widget->property()->setValue(widget->value());
00516 }
00517
00518 void
00519 Editor::slotWidgetRejectInput(Widget *widget)
00520 {
00521 if(!widget || !d->set)
00522 return;
00523
00524 undo();
00525 }
00526
00527 void
00528 Editor::slotClicked(QListViewItem *it)
00529 {
00530 d->previouslyCollapsedGroupItem = 0;
00531 d->childFormPreviouslyCollapsedGroupItem = 0;
00532
00533 acceptInput();
00534
00535 hideEditor();
00536 if(!it)
00537 return;
00538
00539 EditorItem *item = static_cast<EditorItem*>(it);
00540 Property *p = item ? item->property() : 0;
00541 if(!p)
00542 return;
00543
00544 d->currentItem = item;
00545 d->currentWidget = createWidgetForProperty(p);
00546
00547
00548 showUndoButton( p->isModified() );
00549 if (d->currentWidget) {
00550 if (d->currentWidget->visibleFlag()) {
00551 d->currentWidget->show();
00552 if (hasParent( this, kapp->focusWidget() ))
00553 d->currentWidget->setFocus();
00554 }
00555 }
00556
00557 d->justClickedItem = true;
00558 }
00559
00560 void
00561 Editor::slotCurrentChanged(QListViewItem *item)
00562 {
00563 if (item == firstChild()) {
00564 QListViewItem *oldItem = item;
00565 while (item && (!item->isSelectable() || !item->isVisible()))
00566 item = item->itemBelow();
00567 if (item && item != oldItem) {
00568 setSelected(item,true);
00569 return;
00570 }
00571 }
00572 }
00573
00574 void
00575 Editor::slotSetWillBeCleared()
00576 {
00577 if (d->currentWidget) {
00578 acceptInput();
00579 d->currentWidget->setProperty(0);
00580 }
00581 clear();
00582 }
00583
00584 void
00585 Editor::slotSetWillBeDeleted()
00586 {
00587 clear();
00588 d->set = 0;
00589 }
00590
00591 Widget*
00592 Editor::createWidgetForProperty(Property *property, bool changeWidgetProperty)
00593 {
00594
00595 QGuardedPtr<Widget> widget = d->widgetCache[property];
00596
00597 if(!widget) {
00598 widget = FactoryManager::self()->createWidgetForProperty(property);
00599 if (!widget)
00600 return 0;
00601 widget->setReadOnly( (d->set && d->set->isReadOnly()) || property->isReadOnly() );
00602 d->widgetCache[property] = widget;
00603 widget->setProperty(0);
00604 widget->hide();
00605 connect(widget, SIGNAL(valueChanged(Widget*)),
00606 this, SLOT(slotWidgetValueChanged(Widget*)) );
00607 connect(widget, SIGNAL(acceptInput(Widget*)),
00608 this, SLOT(slotWidgetAcceptInput(Widget*)) );
00609 connect(widget, SIGNAL(rejectInput(Widget*)),
00610 this, SLOT(slotWidgetRejectInput(Widget*)) );
00611 }
00612
00613
00614 updateEditorGeometry(d->currentItem, widget);
00615
00616 if(widget && !widget->property() || changeWidgetProperty)
00617 widget->setProperty(property);
00618
00619
00620
00621
00622
00623 return widget;
00624 }
00625
00626
00627 void
00628 Editor::clearWidgetCache()
00629 {
00630 for(QMap<Property*, Widget*>::iterator it = d->widgetCache.begin(); it != d->widgetCache.end(); ++it)
00631 delete it.data();
00632 d->widgetCache.clear();
00633 }
00634
00635 void
00636 Editor::updateEditorGeometry(bool forceUndoButtonSettings, bool undoButtonVisible)
00637 {
00638 updateEditorGeometry(d->currentItem, d->currentWidget,
00639 forceUndoButtonSettings, undoButtonVisible);
00640 }
00641
00642 void
00643 Editor::updateEditorGeometry(EditorItem *item, Widget* widget,
00644 bool forceUndoButtonSettings, bool undoButtonVisible)
00645 {
00646 if(!item || !widget)
00647 return;
00648
00649 int placeForUndoButton;
00650 if (forceUndoButtonSettings ? undoButtonVisible : d->undoButton->isVisible())
00651 placeForUndoButton = d->undoButton->width();
00652 else
00653 placeForUndoButton = widget->leavesTheSpaceForRevertButton() ? d->undoButton->width() : 0;
00654
00655 QRect r;
00656 int y = itemPos(item);
00657 r.setX(header()->sectionPos(1)-(widget->hasBorders()?1:0));
00658 r.setY(y-(widget->hasBorders()?1:0));
00659 r.setWidth(header()->sectionSize(1)+(widget->hasBorders()?1:0)
00660 - placeForUndoButton);
00661 r.setHeight(item->height()+(widget->hasBorders()?1:-1));
00662
00663
00664 if (visibleWidth() < r.right())
00665 r.setRight(visibleWidth());
00666
00667 moveChild(widget, r.x(), r.y());
00668 widget->resize(r.size());
00669 qApp->eventLoop()->processEvents(QEventLoop::AllEvents);
00670 }
00671
00672 void
00673 Editor::hideEditor()
00674 {
00675 d->currentItem = 0;
00676 QWidget *cw = d->currentWidget;
00677 if(cw) {
00678 d->currentWidget = 0;
00679 cw->hide();
00680 }
00681 d->undoButton->hide();
00682 }
00683
00684 void
00685 Editor::showUndoButton( bool show )
00686 {
00687 if (!d->currentItem || !d->currentWidget || (d->currentWidget && d->currentWidget->isReadOnly()))
00688 return;
00689
00690 int y = viewportToContents(QPoint(0, itemRect(d->currentItem).y())).y();
00691 QRect geometry(columnWidth(0), y, columnWidth(1) + 1, d->currentItem->height());
00692 d->undoButton->resize(d->baseRowHeight, d->baseRowHeight);
00693
00694 updateEditorGeometry(true, show);
00695
00696 if (!show) {
00697
00698
00699
00700
00701
00702
00703 d->undoButton->hide();
00704 return;
00705 }
00706
00707 QPoint p = contentsToViewport(QPoint(0, geometry.y()));
00708 d->undoButton->move(geometry.x() + geometry.width()
00709 -((d->currentWidget && d->currentWidget->hasBorders())?1:0)
00710 - d->undoButton->width(), p.y());
00711
00712
00713
00714
00715 d->undoButton->show();
00716 }
00717
00718 void
00719 Editor::slotExpanded(QListViewItem *item)
00720 {
00721 if (!item)
00722 return;
00723
00724
00725 if (!selectedItem() && dynamic_cast<EditorGroupItem*>(item) && d->previouslyCollapsedGroupItem == item
00726 && d->childFormPreviouslyCollapsedGroupItem) {
00727 setSelected(d->childFormPreviouslyCollapsedGroupItem, true);
00728 setCurrentItem(selectedItem());
00729 slotClicked(selectedItem());
00730 }
00731 updateEditorGeometry();
00732 }
00733
00734 void
00735 Editor::slotCollapsed(QListViewItem *item)
00736 {
00737 if (!item)
00738 return;
00739
00740 if (dynamic_cast<EditorGroupItem*>(item)) {
00741 for (QListViewItem *i = selectedItem(); i; i = i->parent()) {
00742 if (i->parent()==item) {
00743 d->previouslyCollapsedGroupItem = item;
00744 d->childFormPreviouslyCollapsedGroupItem = selectedItem();
00745 hideEditor();
00746 setSelected(selectedItem(), false);
00747 setSelected(item->nextSibling(), true);
00748 break;
00749 }
00750 }
00751 }
00752 updateEditorGeometry();
00753 }
00754
00755 void
00756 Editor::slotColumnSizeChanged(int section, int oldSize, int newSize)
00757 {
00758 Q_UNUSED(section);
00759 Q_UNUSED(oldSize);
00760 Q_UNUSED(newSize);
00761 updateEditorGeometry();
00762 for (QListViewItemIterator it(this); it.current(); ++it) {
00763
00764
00765
00766 }
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780 update();
00781 }
00782
00783 void
00784 Editor::slotColumnSizeChanged(int section)
00785 {
00786 setColumnWidth(1, viewport()->width() - columnWidth(0));
00787 slotColumnSizeChanged(section, 0, header()->sectionSize(section));
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797 if(d->undoButton->isVisible())
00798 showUndoButton(true);
00799 else
00800 updateEditorGeometry();
00801 }
00802
00803 QSize
00804 Editor::sizeHint() const
00805 {
00806 return QSize( QFontMetrics(font()).width(columnText(0)+columnText(1)+" "),
00807 KListView::sizeHint().height());
00808 }
00809
00810 void
00811 Editor::setFocus()
00812 {
00813 EditorItem *item = static_cast<EditorItem *>(selectedItem());
00814 if (item) {
00815 if (!d->justClickedItem)
00816 ensureItemVisible(item);
00817 d->justClickedItem = false;
00818 }
00819 else {
00820
00821 item = static_cast<EditorItem *>(itemAt(QPoint(10,1)));
00822 if (item) {
00823 ensureItemVisible(item);
00824 setSelected(item, true);
00825 }
00826 }
00827 if (d->currentWidget) {
00828
00829 d->currentWidget->setFocus();
00830 }
00831 else {
00832
00833 KListView::setFocus();
00834 }
00835 }
00836
00837 void
00838 Editor::resizeEvent(QResizeEvent *ev)
00839 {
00840 KListView::resizeEvent(ev);
00841 if(d->undoButton->isVisible())
00842 showUndoButton(true);
00843 update();
00844 }
00845
00846 bool
00847 Editor::eventFilter( QObject * watched, QEvent * e )
00848 {
00849 if ((watched==this || watched==viewport()) && e->type()==QEvent::KeyPress) {
00850 if (handleKeyPress(static_cast<QKeyEvent*>(e)))
00851 return true;
00852 }
00853 return KListView::eventFilter(watched, e);
00854 }
00855
00856 bool
00857 Editor::handleKeyPress(QKeyEvent* ev)
00858 {
00859 const int k = ev->key();
00860 const Qt::ButtonState s = ev->state();
00861
00862
00863 QListViewItem *item = 0;
00864
00865 if ( ((s == NoButton) && (k == Key_Up)) || (k==Key_BackTab) ) {
00866
00867 item = selectedItem() ? selectedItem()->itemAbove() : 0;
00868 while (item && (!item->isSelectable() || !item->isVisible()))
00869 item = item->itemAbove();
00870 if (!item)
00871 return true;
00872 }
00873 else if( (s == NoButton) && ((k == Key_Down) || (k == Key_Tab)) ) {
00874
00875 item = selectedItem() ? selectedItem()->itemBelow() : 0;
00876 while (item && (!item->isSelectable() || !item->isVisible()))
00877 item = item->itemBelow();
00878 if (!item)
00879 return true;
00880 }
00881 else if( (s==NoButton) && (k==Key_Home) ) {
00882 if (d->currentWidget && d->currentWidget->hasFocus())
00883 return false;
00884
00885 item = firstChild();
00886 while (item && (!item->isSelectable() || !item->isVisible()))
00887 item = item->itemBelow();
00888 }
00889 else if( (s==NoButton) && (k==Key_End) ) {
00890 if (d->currentWidget && d->currentWidget->hasFocus())
00891 return false;
00892
00893 item = selectedItem();
00894 QListViewItem *lastVisible = item;
00895 while (item) {
00896 item = item->itemBelow();
00897 if (item && item->isSelectable() && item->isVisible())
00898 lastVisible = item;
00899 }
00900 item = lastVisible;
00901 }
00902
00903 if(item) {
00904 ev->accept();
00905 ensureItemVisible(item);
00906 setSelected(item, true);
00907 return true;
00908 }
00909 return false;
00910 }
00911
00912 void
00913 Editor::updateFont()
00914 {
00915 setFont(parentWidget()->font());
00916 d->baseRowHeight = QFontMetrics(parentWidget()->font()).height() + itemMargin() * 2;
00917 if (!d->currentItem)
00918 d->undoButton->resize(d->baseRowHeight, d->baseRowHeight);
00919 else {
00920 showUndoButton(d->undoButton->isVisible());
00921 updateEditorGeometry();
00922 }
00923 }
00924
00925 bool
00926 Editor::event( QEvent * e )
00927 {
00928 if (e->type()==QEvent::ParentFontChange) {
00929 updateFont();
00930 }
00931 return KListView::event(e);
00932 }
00933
00934 void
00935 Editor::contentsMousePressEvent( QMouseEvent * e )
00936 {
00937 QListViewItem *item = itemAt(e->pos());
00938 if (dynamic_cast<EditorGroupItem*>(item)) {
00939 setOpen( item, !isOpen(item) );
00940 return;
00941 }
00942 KListView::contentsMousePressEvent(e);
00943 }
00944
00945 #include "editor.moc"