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