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