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
00216 if(!it.key().isEmpty() && !it.data().isEmpty() && map.count() > 1)
00217 groupItem = new EditorGroupItem(d->topItem, d->set->groupDescription(it.key()) );
00218
00219 QValueList<QCString>::ConstIterator it2 = it.data().constBegin();
00220 for( ; it2 != it.data().constEnd(); ++it2)
00221 addItem(*it2, groupItem);
00222 }
00223
00224 }
00225
00226
00227
00228 if (firstChild())
00229 {
00230 setCurrentItem(firstChild());
00231 setSelected(firstChild(), true);
00232 slotClicked(firstChild());
00233 }
00234 setUpdatesEnabled(true);
00235
00236 triggerUpdate();
00237 }
00238
00239 void
00240 Editor::addItem(const QCString &name, EditorItem *parent)
00241 {
00242 if(!d->set || !d->set->contains(name))
00243 return;
00244
00245 Property *property = &(d->set->property(name));
00246 if(!property || !property->isVisible()) {
00247
00248 return;
00249 }
00250 QListViewItem *last = parent ? parent->firstChild() : d->topItem->firstChild();
00251 while(last && last->nextSibling())
00252 last = last->nextSibling();
00253
00254 EditorItem *item=0;
00255 if(parent)
00256 item = new EditorItem(this, parent, property, last);
00257 else
00258 item = new EditorItem(this, d->topItem, property, last);
00259 d->itemDict.insert(name, item);
00260
00261
00262 item->setOpen(true);
00263 if(!property->children())
00264 return;
00265
00266 last = 0;
00267 QValueList<Property*>::ConstIterator endIt = property->children()->constEnd();
00268 for(QValueList<Property*>::ConstIterator it = property->children()->constBegin(); it != endIt; ++it) {
00270 if( *it && (*it)->isVisible() )
00271 last = new EditorItem(this, item, *it, last);
00272 }
00273 }
00274
00275 void
00276 Editor::changeSet(Set *set, bool preservePrevSelection)
00277 {
00278 if (d->insideSlotValueChanged) {
00279
00280
00281
00282 d->setListLater_list = set;
00283 d->preservePrevSelection_preservePrevSelection = preservePrevSelection;
00284 qApp->eventLoop()->processEvents(QEventLoop::AllEvents);
00285 if (!d->setListLater_set) {
00286 d->setListLater_set = true;
00287 d->changeSetLaterTimer.start(10, true);
00288 }
00289 return;
00290 }
00291
00292 if (d->set) {
00293 slotWidgetAcceptInput(d->currentWidget);
00294
00295 if (d->currentItem)
00296 d->set->setPrevSelection( d->currentItem->property()->name() );
00297 d->set->disconnect(this);
00298 }
00299
00300 QCString selectedPropertyName1, selectedPropertyName2;
00301 if (preservePrevSelection) {
00302
00303
00304 if(set)
00305 selectedPropertyName1 = set->prevSelection();
00306
00307 if(d->set)
00308 selectedPropertyName2 = d->set->prevSelection();
00309 }
00310
00311 d->set = set;
00312 if (d->set) {
00313
00314 connect(d->set, SIGNAL(propertyChanged(KoProperty::Set&, KoProperty::Property&)),
00315 this, SLOT(slotPropertyChanged(KoProperty::Set&, KoProperty::Property&)));
00316 connect(d->set, SIGNAL(propertyReset(KoProperty::Set&, KoProperty::Property&)),
00317 this, SLOT(slotPropertyReset(KoProperty::Set&, KoProperty::Property&)));
00318 connect(d->set,SIGNAL(aboutToBeCleared()), this, SLOT(slotSetWillBeCleared()));
00319 connect(d->set,SIGNAL(aboutToBeDeleted()), this, SLOT(slotSetWillBeDeleted()));
00320 }
00321
00322 fill();
00323
00324 emit propertySetChanged(d->set);
00325
00326 if (d->set) {
00327
00328 EditorItem * item = 0;
00329 if (!selectedPropertyName2.isEmpty())
00330 item = d->itemDict[selectedPropertyName2];
00331 if (!item && !selectedPropertyName1.isEmpty())
00332 item = d->itemDict[selectedPropertyName1];
00333
00334 if (item) {
00335 d->itemToSelectLater = item;
00336 QTimer::singleShot(10, this, SLOT(selectItemLater()));
00337
00338
00339
00340
00341 }
00342 }
00343 }
00344
00346 void Editor::selectItemLater()
00347 {
00348 if (!d->itemToSelectLater)
00349 return;
00350 EditorItem *item = d->itemToSelectLater;
00351 d->itemToSelectLater = 0;
00352 setSelected(item, true);
00353 ensureItemVisible(item);
00354 }
00355
00357 void
00358 Editor::changeSetLater()
00359 {
00360 qApp->eventLoop()->processEvents(QEventLoop::AllEvents);
00361 if (kapp->hasPendingEvents()) {
00362 d->changeSetLaterTimer.start(10, true);
00363 return;
00364 }
00365 d->setListLater_set = false;
00366 if (!d->setListLater_list)
00367 return;
00368
00369 bool b = d->insideSlotValueChanged;
00370 d->insideSlotValueChanged = false;
00371 changeSet(d->setListLater_list, d->preservePrevSelection_preservePrevSelection);
00372 d->insideSlotValueChanged = b;
00373 }
00374
00375 void
00376 Editor::clear(bool editorOnly)
00377 {
00378 d->itemToSelectLater = 0;
00379 hideEditor();
00380
00381 if(!editorOnly) {
00382 qApp->eventLoop()->processEvents(QEventLoop::AllEvents);
00383 if(d->set)
00384 d->set->disconnect(this);
00385 clearWidgetCache();
00386 KListView::clear();
00387 d->itemDict.clear();
00388 d->topItem = 0;
00389 }
00390 }
00391
00392 void
00393 Editor::undo()
00394 {
00395 if(!d->currentWidget || !d->currentItem || (d->set && d->set->isReadOnly()) || (d->currentWidget && d->currentWidget->isReadOnly()))
00396 return;
00397
00398 int propertySync = d->currentWidget->property()->autoSync();
00399 bool sync = (propertySync != 0 && propertySync != 1) ?
00400 d->sync : (propertySync!=0);
00401
00402 if(sync)
00403 d->currentItem->property()->resetValue();
00404 if (d->currentWidget && d->currentItem) {
00405 d->currentWidget->setValue( d->currentItem->property()->value());
00406 repaintItem(d->currentItem);
00407 }
00408 }
00409
00410 void
00411 Editor::slotPropertyChanged(Set& set, Property& property)
00412 {
00413 if (!d->slotPropertyChanged_enabled)
00414 return;
00415 if(&set != d->set)
00416 return;
00417
00418 if (d->currentItem && d->currentItem->property() == &property) {
00419 d->currentWidget->setValue(property.value(), false);
00420 for(QListViewItem *item = d->currentItem->firstChild(); item; item = item->nextSibling())
00421 repaintItem(item);
00422 }
00423 else {
00424
00425 EditorItem *item = d->itemDict[property.name()];
00426 if(!item && property.parent())
00427 item = d->itemDict[property.parent()->name()];
00428 if (item) {
00429 repaintItem(item);
00430 for(QListViewItem *it = item->firstChild(); it; it = it->nextSibling())
00431 repaintItem(it);
00432 }
00433 }
00434
00436 #if 0
00437 if (property.parent() && property.parent()->type()==Rect) {
00438 const int delta = property.value().toInt()-previousValue.toInt();
00439 if (property.type()==Rect_X) {
00440 property.parent()->child("width")->setValue(delta, false);
00441 }
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455 }
00456 #endif
00457 showUndoButton( property.isModified() );
00458 }
00459
00460 void
00461 Editor::slotPropertyReset(Set& set, Property& property)
00462 {
00463 if(&set != d->set)
00464 return;
00465
00466 if (d->currentItem && d->currentItem->property() == &property) {
00467 d->currentWidget->setValue(property.value(), false);
00468 for(QListViewItem *item = d->currentItem->firstChild(); item; item = item->nextSibling())
00469 repaintItem(item);
00470 }
00471 else {
00472 EditorItem *item = d->itemDict[property.name()];
00473
00474 if(!item && property.parent())
00475 item = d->itemDict[property.parent()->name()];
00476 if (item) {
00477 repaintItem(item);
00478 for(QListViewItem *it = item->firstChild(); it; it = it->nextSibling())
00479 repaintItem(it);
00480 }
00481 }
00482
00483 showUndoButton( false );
00484 }
00485
00486 void
00487 Editor::slotWidgetValueChanged(Widget *widget)
00488 {
00489 if(!widget || !d->set || (d->set && d->set->isReadOnly()) || (widget && widget->isReadOnly()) || !widget->property())
00490 return;
00491
00492 d->insideSlotValueChanged = true;
00493
00494 QVariant value = widget->value();
00495 int propertySync = widget->property()->autoSync();
00496 bool sync = (propertySync != 0 && propertySync != 1) ?
00497 d->sync : (propertySync!=0);
00498
00499 if(sync) {
00500 d->slotPropertyChanged_enabled = false;
00501 QGuardedPtr<Widget> pWidget = widget;
00502 widget->property()->setValue(value);
00503 if (pWidget)
00504 showUndoButton( pWidget->property()->isModified() );
00505 d->slotPropertyChanged_enabled = true;
00506 }
00507
00508 d->insideSlotValueChanged = false;
00509 }
00510
00511 void
00512 Editor::acceptInput()
00513 {
00514 slotWidgetAcceptInput(d->currentWidget);
00515 }
00516
00517 void
00518 Editor::slotWidgetAcceptInput(Widget *widget)
00519 {
00520 if(!widget || !d->set || !widget->property() || (d->set && d->set->isReadOnly()) || (widget && widget->isReadOnly()))
00521 return;
00522
00523 widget->property()->setValue(widget->value());
00524 }
00525
00526 void
00527 Editor::slotWidgetRejectInput(Widget *widget)
00528 {
00529 if(!widget || !d->set)
00530 return;
00531
00532 undo();
00533 }
00534
00535 void
00536 Editor::slotClicked(QListViewItem *it)
00537 {
00538 d->previouslyCollapsedGroupItem = 0;
00539 d->childFormPreviouslyCollapsedGroupItem = 0;
00540
00541 acceptInput();
00542
00543 hideEditor();
00544 if(!it)
00545 return;
00546
00547 EditorItem *item = static_cast<EditorItem*>(it);
00548 Property *p = item ? item->property() : 0;
00549 if(!p)
00550 return;
00551
00552 d->currentItem = item;
00553 d->currentWidget = createWidgetForProperty(p);
00554
00555
00556 showUndoButton( p->isModified() );
00557 if (d->currentWidget) {
00558 if (d->currentWidget->visibleFlag()) {
00559 d->currentWidget->show();
00560 if (hasParent( this, kapp->focusWidget() ))
00561 d->currentWidget->setFocus();
00562 }
00563 }
00564
00565 d->justClickedItem = true;
00566 }
00567
00568 void
00569 Editor::slotCurrentChanged(QListViewItem *item)
00570 {
00571 if (item == firstChild()) {
00572 QListViewItem *oldItem = item;
00573 while (item && (!item->isSelectable() || !item->isVisible()))
00574 item = item->itemBelow();
00575 if (item && item != oldItem) {
00576 setSelected(item,true);
00577 return;
00578 }
00579 }
00580 }
00581
00582 void
00583 Editor::slotSetWillBeCleared()
00584 {
00585 d->itemToSelectLater = 0;
00586 if (d->currentWidget) {
00587 acceptInput();
00588 d->currentWidget->setProperty(0);
00589 }
00590 clear();
00591 }
00592
00593 void
00594 Editor::slotSetWillBeDeleted()
00595 {
00596 clear();
00597 d->set = 0;
00598 }
00599
00600 Widget*
00601 Editor::createWidgetForProperty(Property *property, bool changeWidgetProperty)
00602 {
00603
00604 QGuardedPtr<Widget> widget = d->widgetCache[property];
00605
00606 if(!widget) {
00607 widget = FactoryManager::self()->createWidgetForProperty(property);
00608 if (!widget)
00609 return 0;
00610 widget->setReadOnly( (d->set && d->set->isReadOnly()) || property->isReadOnly() );
00611 d->widgetCache[property] = widget;
00612 widget->setProperty(0);
00613 widget->hide();
00614 connect(widget, SIGNAL(valueChanged(Widget*)),
00615 this, SLOT(slotWidgetValueChanged(Widget*)) );
00616 connect(widget, SIGNAL(acceptInput(Widget*)),
00617 this, SLOT(slotWidgetAcceptInput(Widget*)) );
00618 connect(widget, SIGNAL(rejectInput(Widget*)),
00619 this, SLOT(slotWidgetRejectInput(Widget*)) );
00620 }
00621
00622
00623 updateEditorGeometry(d->currentItem, widget);
00624
00625 if(widget && (!widget->property() || changeWidgetProperty))
00626 widget->setProperty(property);
00627
00628
00629
00630
00631
00632 return widget;
00633 }
00634
00635
00636 void
00637 Editor::clearWidgetCache()
00638 {
00639 for(QMap<Property*, Widget*>::iterator it = d->widgetCache.begin(); it != d->widgetCache.end(); ++it)
00640 it.data()->deleteLater();
00641
00642 d->widgetCache.clear();
00643 }
00644
00645 void
00646 Editor::updateEditorGeometry(bool forceUndoButtonSettings, bool undoButtonVisible)
00647 {
00648 updateEditorGeometry(d->currentItem, d->currentWidget,
00649 forceUndoButtonSettings, undoButtonVisible);
00650 }
00651
00652 void
00653 Editor::updateEditorGeometry(EditorItem *item, Widget* widget,
00654 bool forceUndoButtonSettings, bool undoButtonVisible)
00655 {
00656 if(!item || !widget)
00657 return;
00658
00659 int placeForUndoButton;
00660 if (forceUndoButtonSettings ? undoButtonVisible : d->undoButton->isVisible())
00661 placeForUndoButton = d->undoButton->width();
00662 else
00663 placeForUndoButton = widget->leavesTheSpaceForRevertButton() ? d->undoButton->width() : 0;
00664
00665 QRect r;
00666 int y = itemPos(item);
00667 r.setX(header()->sectionPos(1)-(widget->hasBorders()?1:0));
00668 r.setY(y-(widget->hasBorders()?1:0));
00669 r.setWidth(header()->sectionSize(1)+(widget->hasBorders()?1:0)
00670 - placeForUndoButton);
00671 r.setHeight(item->height()+(widget->hasBorders()?1:-1));
00672
00673
00674 if (visibleWidth() < r.right())
00675 r.setRight(visibleWidth());
00676
00677 moveChild(widget, r.x(), r.y());
00678 widget->resize(r.size());
00679 qApp->eventLoop()->processEvents(QEventLoop::AllEvents);
00680 }
00681
00682 void
00683 Editor::hideEditor()
00684 {
00685 d->currentItem = 0;
00686 QWidget *cw = d->currentWidget;
00687 if(cw) {
00688 d->currentWidget = 0;
00689 cw->hide();
00690 }
00691 d->undoButton->hide();
00692 }
00693
00694 void
00695 Editor::showUndoButton( bool show )
00696 {
00697 if (!d->currentItem || !d->currentWidget || (d->currentWidget && d->currentWidget->isReadOnly()))
00698 return;
00699
00700 int y = viewportToContents(QPoint(0, itemRect(d->currentItem).y())).y();
00701 QRect geometry(columnWidth(0), y, columnWidth(1) + 1, d->currentItem->height());
00702 d->undoButton->resize(d->baseRowHeight, d->baseRowHeight);
00703
00704 updateEditorGeometry(true, show);
00705
00706 if (!show) {
00707
00708
00709
00710
00711
00712
00713 d->undoButton->hide();
00714 return;
00715 }
00716
00717 QPoint p = contentsToViewport(QPoint(0, geometry.y()));
00718 d->undoButton->move(geometry.x() + geometry.width()
00719 -((d->currentWidget && d->currentWidget->hasBorders())?1:0)
00720 - d->undoButton->width(), p.y());
00721
00722
00723
00724
00725 d->undoButton->show();
00726 }
00727
00728 void
00729 Editor::slotExpanded(QListViewItem *item)
00730 {
00731 if (!item)
00732 return;
00733
00734
00735 if (!selectedItem() && dynamic_cast<EditorGroupItem*>(item) && d->previouslyCollapsedGroupItem == item
00736 && d->childFormPreviouslyCollapsedGroupItem) {
00737 setSelected(d->childFormPreviouslyCollapsedGroupItem, true);
00738 setCurrentItem(selectedItem());
00739 slotClicked(selectedItem());
00740 }
00741 updateEditorGeometry();
00742 }
00743
00744 void
00745 Editor::slotCollapsed(QListViewItem *item)
00746 {
00747 if (!item)
00748 return;
00749
00750 if (dynamic_cast<EditorGroupItem*>(item)) {
00751 for (QListViewItem *i = selectedItem(); i; i = i->parent()) {
00752 if (i->parent()==item) {
00753 d->previouslyCollapsedGroupItem = item;
00754 d->childFormPreviouslyCollapsedGroupItem = selectedItem();
00755 hideEditor();
00756 setSelected(selectedItem(), false);
00757 setSelected(item->nextSibling(), true);
00758 break;
00759 }
00760 }
00761 }
00762 updateEditorGeometry();
00763 }
00764
00765 void
00766 Editor::slotColumnSizeChanged(int section, int oldSize, int newSize)
00767 {
00768 Q_UNUSED(section);
00769 Q_UNUSED(oldSize);
00770 Q_UNUSED(newSize);
00771 updateEditorGeometry();
00772 for (QListViewItemIterator it(this); it.current(); ++it) {
00773
00774
00775
00776 }
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790 update();
00791 }
00792
00793 void
00794 Editor::slotColumnSizeChanged(int section)
00795 {
00796 setColumnWidth(1, viewport()->width() - columnWidth(0));
00797 slotColumnSizeChanged(section, 0, header()->sectionSize(section));
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807 if(d->undoButton->isVisible())
00808 showUndoButton(true);
00809 else
00810 updateEditorGeometry();
00811 }
00812
00813 QSize
00814 Editor::sizeHint() const
00815 {
00816 return QSize( QFontMetrics(font()).width(columnText(0)+columnText(1)+" "),
00817 KListView::sizeHint().height());
00818 }
00819
00820 void
00821 Editor::setFocus()
00822 {
00823 EditorItem *item = static_cast<EditorItem *>(selectedItem());
00824 if (item) {
00825 if (!d->justClickedItem)
00826 ensureItemVisible(item);
00827 d->justClickedItem = false;
00828 }
00829 else {
00830
00831 item = static_cast<EditorItem *>(itemAt(QPoint(10,1)));
00832 if (item) {
00833 ensureItemVisible(item);
00834 setSelected(item, true);
00835 }
00836 }
00837 if (d->currentWidget) {
00838
00839 d->currentWidget->setFocus();
00840 }
00841 else {
00842
00843 KListView::setFocus();
00844 }
00845 }
00846
00847 void
00848 Editor::resizeEvent(QResizeEvent *ev)
00849 {
00850 KListView::resizeEvent(ev);
00851 if(d->undoButton->isVisible())
00852 showUndoButton(true);
00853 update();
00854 }
00855
00856 bool
00857 Editor::eventFilter( QObject * watched, QEvent * e )
00858 {
00859 if ((watched==this || watched==viewport()) && e->type()==QEvent::KeyPress) {
00860 if (handleKeyPress(static_cast<QKeyEvent*>(e)))
00861 return true;
00862 }
00863 return KListView::eventFilter(watched, e);
00864 }
00865
00866 bool
00867 Editor::handleKeyPress(QKeyEvent* ev)
00868 {
00869 const int k = ev->key();
00870 const Qt::ButtonState s = ev->state();
00871
00872
00873 QListViewItem *item = 0;
00874
00875 if ( ((s == NoButton) && (k == Key_Up)) || (k==Key_BackTab) ) {
00876
00877 item = selectedItem() ? selectedItem()->itemAbove() : 0;
00878 while (item && (!item->isSelectable() || !item->isVisible()))
00879 item = item->itemAbove();
00880 if (!item)
00881 return true;
00882 }
00883 else if( (s == NoButton) && ((k == Key_Down) || (k == Key_Tab)) ) {
00884
00885 item = selectedItem() ? selectedItem()->itemBelow() : 0;
00886 while (item && (!item->isSelectable() || !item->isVisible()))
00887 item = item->itemBelow();
00888 if (!item)
00889 return true;
00890 }
00891 else if( (s==NoButton) && (k==Key_Home) ) {
00892 if (d->currentWidget && d->currentWidget->hasFocus())
00893 return false;
00894
00895 item = firstChild();
00896 while (item && (!item->isSelectable() || !item->isVisible()))
00897 item = item->itemBelow();
00898 }
00899 else if( (s==NoButton) && (k==Key_End) ) {
00900 if (d->currentWidget && d->currentWidget->hasFocus())
00901 return false;
00902
00903 item = selectedItem();
00904 QListViewItem *lastVisible = item;
00905 while (item) {
00906 item = item->itemBelow();
00907 if (item && item->isSelectable() && item->isVisible())
00908 lastVisible = item;
00909 }
00910 item = lastVisible;
00911 }
00912
00913 if(item) {
00914 ev->accept();
00915 ensureItemVisible(item);
00916 setSelected(item, true);
00917 return true;
00918 }
00919 return false;
00920 }
00921
00922 void
00923 Editor::updateFont()
00924 {
00925 setFont(parentWidget()->font());
00926 d->baseRowHeight = QFontMetrics(parentWidget()->font()).height() + itemMargin() * 2;
00927 if (!d->currentItem)
00928 d->undoButton->resize(d->baseRowHeight, d->baseRowHeight);
00929 else {
00930 showUndoButton(d->undoButton->isVisible());
00931 updateEditorGeometry();
00932 }
00933 }
00934
00935 bool
00936 Editor::event( QEvent * e )
00937 {
00938 if (e->type()==QEvent::ParentFontChange) {
00939 updateFont();
00940 }
00941 return KListView::event(e);
00942 }
00943
00944 void
00945 Editor::contentsMousePressEvent( QMouseEvent * e )
00946 {
00947 QListViewItem *item = itemAt(e->pos());
00948 if (dynamic_cast<EditorGroupItem*>(item)) {
00949 setOpen( item, !isOpen(item) );
00950 return;
00951 }
00952 KListView::contentsMousePressEvent(e);
00953 }
00954
00955 #include "editor.moc"