From a6d58bb6052ac8cb01805a48c4ad2f129126116f Mon Sep 17 00:00:00 2001 From: tpearson Date: Wed, 24 Feb 2010 02:13:59 +0000 Subject: Added KDE3 version of kvirc git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/kvirc@1095341 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- src/kvilib/tal/kvi_tal_listview.cpp | 1542 +++++++++++++++++++++++++++++++++++ 1 file changed, 1542 insertions(+) create mode 100644 src/kvilib/tal/kvi_tal_listview.cpp (limited to 'src/kvilib/tal/kvi_tal_listview.cpp') diff --git a/src/kvilib/tal/kvi_tal_listview.cpp b/src/kvilib/tal/kvi_tal_listview.cpp new file mode 100644 index 00000000..01b253b3 --- /dev/null +++ b/src/kvilib/tal/kvi_tal_listview.cpp @@ -0,0 +1,1542 @@ +//============================================================================= +// +// File : kvi_tal_listview.cpp +// Creation date : Mon Jan 22 2007 11:25:08 by Szymon Stefanek +// +// This file is part of the KVirc irc client distribution +// Copyright (C) 2007 Szymon Stefanek (pragma at kvirc dot net) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#define __KVILIB__ +#include "kvi_tal_listview.h" + +#include "kvi_pointerhashtable.h" + + +#ifdef COMPILE_USE_QT4 + #include + #include + #include + #include + #include + #include + #include + + static QStyleOptionQ3ListView getStyleOption(const Q3ListView *lv, const Q3ListViewItem *item) + { + QStyleOptionQ3ListView opt; + opt.init(lv); + opt.subControls = QStyle::SC_None; + opt.activeSubControls = QStyle::SC_None; + QWidget *vp = lv->viewport(); + opt.viewportPalette = vp->palette(); + opt.viewportBGRole = vp->backgroundRole(); + opt.itemMargin = lv->itemMargin(); + opt.sortColumn = 0; + opt.treeStepSize = lv->treeStepSize(); + opt.rootIsDecorated = lv->rootIsDecorated(); + bool firstItem = true; + while (item) { + QStyleOptionQ3ListViewItem lvi; + lvi.height = item->height(); + lvi.totalHeight = item->totalHeight(); + lvi.itemY = item->itemPos(); + lvi.childCount = item->childCount(); + lvi.features = QStyleOptionQ3ListViewItem::None; + lvi.state = QStyle::State_None; + if (item->isEnabled()) + lvi.state |= QStyle::State_Enabled; + if (item->isOpen()) + lvi.state |= QStyle::State_Open; + if (item->isExpandable()) + lvi.features |= QStyleOptionQ3ListViewItem::Expandable; + if (item->multiLinesEnabled()) + lvi.features |= QStyleOptionQ3ListViewItem::MultiLine; + if (item->isVisible()) + lvi.features |= QStyleOptionQ3ListViewItem::Visible; + if (item->parent() && item->parent()->rtti() == 1 + && static_cast(item->parent())->type() == Q3CheckListItem::Controller) + lvi.features |= QStyleOptionQ3ListViewItem::ParentControl; + opt.items.append(lvi); + if (!firstItem) { + item = item->nextSibling(); + } else { + firstItem = false; + item = item->firstChild(); + } + } + return opt; + } + + KviTalListView::KviTalListView(QWidget * pParent) + : Q3ListView(pParent) + { + connect(this,SIGNAL(selectionChanged(Q3ListViewItem *)),this,SLOT(redirect_selectionChanged(Q3ListViewItem *))); + connect(this,SIGNAL(currentChanged(Q3ListViewItem *)),this,SLOT(redirect_currentChanged(Q3ListViewItem *))); + connect(this,SIGNAL(clicked(Q3ListViewItem *)),this,SLOT(redirect_clicked(Q3ListViewItem *))); + connect(this,SIGNAL(clicked(Q3ListViewItem *,const QPoint &,int)),this,SLOT(redirect_clicked(Q3ListViewItem *,const QPoint &,int))); + connect(this,SIGNAL(pressed(Q3ListViewItem *)),this,SLOT(redirect_pressed(Q3ListViewItem *))); + connect(this,SIGNAL(pressed(Q3ListViewItem *,const QPoint &,int)),this,SLOT(redirect_pressed(Q3ListViewItem *,const QPoint &,int))); + connect(this,SIGNAL(doubleClicked(Q3ListViewItem *)),this,SLOT(redirect_doubleClicked(Q3ListViewItem *))); + connect(this,SIGNAL(doubleClicked(Q3ListViewItem *,const QPoint &,int)),this,SLOT(redirect_doubleClicked(Q3ListViewItem *,const QPoint &,int))); + connect(this,SIGNAL(returnPressed(Q3ListViewItem *)),this,SLOT(redirect_returnPressed(Q3ListViewItem *))); + connect(this,SIGNAL(spacePressed(Q3ListViewItem *)),this,SLOT(redirect_spacePressed(Q3ListViewItem *))); + connect(this,SIGNAL(rightButtonClicked(Q3ListViewItem *,const QPoint &,int)),this,SLOT(redirect_rightButtonClicked(Q3ListViewItem *,const QPoint &,int))); + connect(this,SIGNAL(rightButtonPressed(Q3ListViewItem *,const QPoint &,int)),this,SLOT(redirect_rightButtonPressed(Q3ListViewItem *,const QPoint &,int))); + connect(this,SIGNAL(mouseButtonClicked(int,Q3ListViewItem *,const QPoint &,int)),this,SLOT(redirect_mouseButtonClicked(int,Q3ListViewItem *,const QPoint &,int))); + connect(this,SIGNAL(mouseButtonPressed(int,Q3ListViewItem *,const QPoint &,int)),this,SLOT(redirect_mouseButtonPressed(int,Q3ListViewItem *,const QPoint &,int))); + connect(this,SIGNAL(contextMenuRequested(Q3ListViewItem *,const QPoint &,int)),this,SLOT(redirect_contextMenuRequested(Q3ListViewItem *,const QPoint &,int))); + connect(this,SIGNAL(onItem(Q3ListViewItem *)),this,SLOT(redirect_onItem(Q3ListViewItem *))); + connect(this,SIGNAL(expanded(Q3ListViewItem *)),this,SLOT(redirect_expanded(Q3ListViewItem *))); + connect(this,SIGNAL(collapsed(Q3ListViewItem *)),this,SLOT(redirect_collapsed(Q3ListViewItem *))); + } + + void KviTalListView::redirect_selectionChanged(Q3ListViewItem * pItem) + { + emit selectionChanged((KviTalListViewItem *)pItem); + } + + void KviTalListView::redirect_currentChanged(Q3ListViewItem * pItem) + { + emit currentChanged((KviTalListViewItem *)pItem); + } + + void KviTalListView::redirect_clicked(Q3ListViewItem * pItem) + { + emit clicked((KviTalListViewItem *)pItem); + } + + void KviTalListView::redirect_clicked(Q3ListViewItem * pItem,const QPoint &pnt,int uColumn) + { + emit clicked((KviTalListViewItem *)pItem,pnt,uColumn); + } + + void KviTalListView::redirect_pressed(Q3ListViewItem * pItem) + { + emit pressed((KviTalListViewItem *)pItem); + } + + void KviTalListView::redirect_pressed(Q3ListViewItem * pItem,const QPoint &pnt,int uColumn) + { + emit pressed((KviTalListViewItem *)pItem,pnt,uColumn); + } + + void KviTalListView::redirect_doubleClicked(Q3ListViewItem * pItem) + { + emit doubleClicked((KviTalListViewItem *)pItem); + } + + void KviTalListView::redirect_doubleClicked(Q3ListViewItem * pItem,const QPoint &pnt,int uColumn) + { + emit doubleClicked((KviTalListViewItem *)pItem,pnt,uColumn); + } + + void KviTalListView::redirect_returnPressed(Q3ListViewItem * pItem) + { + emit returnPressed((KviTalListViewItem *)pItem); + } + + void KviTalListView::redirect_spacePressed(Q3ListViewItem * pItem) + { + emit spacePressed((KviTalListViewItem *)pItem); + } + + void KviTalListView::redirect_rightButtonClicked(Q3ListViewItem * pItem,const QPoint &pnt,int uColumn) + { + emit rightButtonClicked((KviTalListViewItem *)pItem,pnt,uColumn); + } + + void KviTalListView::redirect_rightButtonPressed(Q3ListViewItem * pItem,const QPoint &pnt,int uColumn) + { + emit rightButtonPressed((KviTalListViewItem *)pItem,pnt,uColumn); + } + + void KviTalListView::redirect_mouseButtonClicked(int iButton,Q3ListViewItem * pItem,const QPoint &pnt,int uColumn) + { + emit mouseButtonClicked(iButton,(KviTalListViewItem *)pItem,pnt,uColumn); + } + + void KviTalListView::redirect_mouseButtonPressed(int iButton,Q3ListViewItem * pItem,const QPoint &pnt,int uColumn) + { + emit mouseButtonPressed(iButton,(KviTalListViewItem *)pItem,pnt,uColumn); + } + + void KviTalListView::redirect_contextMenuRequested(Q3ListViewItem * pItem,const QPoint &pnt,int uColumn) + { + emit contextMenuRequested((KviTalListViewItem *)pItem,pnt,uColumn); + } + + void KviTalListView::redirect_onItem(Q3ListViewItem * pItem) + { + emit onItem((KviTalListViewItem *)pItem); + } + + void KviTalListView::redirect_expanded(Q3ListViewItem * pItem) + { + emit expanded((KviTalListViewItem *)pItem); + } + + void KviTalListView::redirect_collapsed(Q3ListViewItem * pItem) + { + emit collapsed((KviTalListViewItem *)pItem); + } + + + struct KviTalCheckListItemPrivate + { + KviTalCheckListItemPrivate(): + exclusive(0), + currentState(KviTalCheckListItem::Off), + tristate(false) {} + + KviTalCheckListItem *exclusive; + KviTalCheckListItem::ToggleState currentState; + QHash statesDict; + bool tristate; + }; + + KviTalCheckListItem::KviTalCheckListItem(KviTalCheckListItem *parent, const QString &text, + Type tt) + : KviTalListViewItem(parent, text, QString()) + { + myType = tt; + init(); + if (myType == RadioButton) { + if (parent->type() != RadioButtonController) + qWarning("KviTalCheckListItem::KviTalCheckListItem(), radio button must be " + "child of a controller"); + else + d->exclusive = parent; + } + } + + KviTalCheckListItem::KviTalCheckListItem(KviTalCheckListItem *parent, KviTalListViewItem *after, + const QString &text, Type tt) + : KviTalListViewItem(parent, after, text) + { + myType = tt; + init(); + if (myType == RadioButton) { + if (parent->type() != RadioButtonController) + qWarning("KviTalCheckListItem::KviTalCheckListItem(), radio button must be " + "child of a controller"); + else + d->exclusive = parent; + } + } + + KviTalCheckListItem::KviTalCheckListItem(KviTalListViewItem *parent, const QString &text, + Type tt) + : KviTalListViewItem(parent, text, QString()) + { + myType = tt; + if (myType == RadioButton) { + qWarning("KviTalCheckListItem::KviTalCheckListItem(), radio button must be " + "child of a KviTalCheckListItem"); + } + init(); + } + + KviTalCheckListItem::KviTalCheckListItem(KviTalListViewItem *parent, KviTalListViewItem *after, + const QString &text, Type tt) + : KviTalListViewItem(parent, after, text) + { + myType = tt; + if (myType == RadioButton) { + qWarning("KviTalCheckListItem::KviTalCheckListItem(), radio button must be " + "child of a KviTalCheckListItem"); + } + init(); + } + + KviTalCheckListItem::KviTalCheckListItem(KviTalListView *parent, const QString &text, + Type tt) + : KviTalListViewItem(parent, text) + { + myType = tt; + if (tt == RadioButton) + qWarning("KviTalCheckListItem::KviTalCheckListItem(), radio button must be " + "child of a KviTalCheckListItem"); + init(); + } + + KviTalCheckListItem::KviTalCheckListItem(KviTalListView *parent, KviTalListViewItem *after, + const QString &text, Type tt) + : KviTalListViewItem(parent, after, text) + { + myType = tt; + if (tt == RadioButton) + qWarning("KviTalCheckListItem::KviTalCheckListItem(), radio button must be " + "child of a KviTalCheckListItem"); + init(); + } + + int KviTalCheckListItem::rtti() const + { + return RTTI; + } + + KviTalCheckListItem::KviTalCheckListItem(KviTalListView *parent, const QString &text, + const QPixmap & p) + : KviTalListViewItem(parent, text) + { + myType = RadioButtonController; + setPixmap(0, p); + init(); + } + + KviTalCheckListItem::KviTalCheckListItem(KviTalListViewItem *parent, const QString &text, + const QPixmap & p) + : KviTalListViewItem(parent, text) + { + myType = RadioButtonController; + setPixmap(0, p); + init(); + } + + void KviTalCheckListItem::init() + { + d = new KviTalCheckListItemPrivate(); + on = false; // ### remove on ver 4 + // CheckBoxControllers by default have tristate set to true + if (myType == CheckBoxController) + setTristate(true); + } + + KviTalCheckListItem::~KviTalCheckListItem() + { + if (myType == RadioButton + && d->exclusive && d->exclusive->d + && d->exclusive->d->exclusive == this) + d->exclusive->turnOffChild(); + d->exclusive = 0; // so the children won't try to access us. + delete d; + d = 0; + } + + void KviTalCheckListItem::setTristate(bool b) + { + if ((myType != CheckBoxController) && (myType != CheckBox)) { + qWarning("KviTalCheckListItem::setTristate(), has no effect on RadioButton " + "or RadioButtonController."); + return; + } + d->tristate = b; + } + + bool KviTalCheckListItem::isTristate() const + { + return d->tristate; + } + + KviTalCheckListItem::ToggleState KviTalCheckListItem::state() const + { + if (!isTristate() && internalState() == NoChange) + return Off; + else + return d->currentState; + } + + KviTalCheckListItem::ToggleState KviTalCheckListItem::internalState() const + { + return d->currentState; + } + + void KviTalCheckListItem::setState(ToggleState s) + { + if (myType == CheckBoxController && state() == NoChange) + updateStoredState(this); + setState(s, true, true); + } + + void KviTalCheckListItem::setState(ToggleState s, bool update, bool store) + { + + if (s == internalState()) + return; + + if (myType == CheckBox) { + setCurrentState(s); + stateChange(state()); + if (update && parent() && parent()->rtti() == 1 + && ((KviTalCheckListItem*)parent())->type() == CheckBoxController) + ((KviTalCheckListItem*)parent())->updateController(update, store); + } else if (myType == CheckBoxController) { + if (s == NoChange && childCount()) { + restoreState(this); + } else { + KviTalListViewItem *item = firstChild(); + int childCount = 0; + while(item) { + if (item->rtti() == 1 && + (((KviTalCheckListItem*)item)->type() == CheckBox || + ((KviTalCheckListItem*)item)->type() == CheckBoxController)) { + KviTalCheckListItem *checkItem = (KviTalCheckListItem*)item; + checkItem->setState(s, false, false); + childCount++; + } + item = item->nextSibling(); + } + if (update) { + if (childCount > 0) { + ToggleState oldState = internalState(); + updateController(false, false); + if (oldState != internalState() && + parent() && parent()->rtti() == 1 && + ((KviTalCheckListItem*)parent())->type() == CheckBoxController) + ((KviTalCheckListItem*)parent())->updateController(update, store); + + updateController(update, store); + } else { + // if there are no children we simply set the CheckBoxController and update its parent + setCurrentState(s); + stateChange(state()); + if (parent() && parent()->rtti() == 1 + && ((KviTalCheckListItem*)parent())->type() == CheckBoxController) + ((KviTalCheckListItem*)parent())->updateController(update, store); + } + } else { + setCurrentState(s); + stateChange(state()); + } + + } + } else if (myType == RadioButton) { + if (s == On) { + if (d->exclusive && d->exclusive->d->exclusive != this) + d->exclusive->turnOffChild(); + setCurrentState(s); + if (d->exclusive) + d->exclusive->d->exclusive = this; + } else { + if (d->exclusive && d->exclusive->d->exclusive == this) + d->exclusive->d->exclusive = 0; + setCurrentState(Off); + } + stateChange(state()); + } + repaint(); + } + + void KviTalCheckListItem::setCurrentState(ToggleState s) + { + ToggleState old = d->currentState; + d->currentState = s; + if (d->currentState == On) + on = true; + else + on = false; + + //#ifndef QT_NO_ACCESSIBILITY + // if (old != d->currentState && listView()) + // QAccessible::updateAccessibility(listView()->viewport(), indexOfItem(this), QAccessible::StateChanged); + //#else + // Q_UNUSED(old); + //#endif + } + + void KviTalCheckListItem::setStoredState(ToggleState newState, KviTalCheckListItem *key) + { + if (myType == CheckBox || myType == CheckBoxController) + d->statesDict[key] = newState; + } + + KviTalCheckListItem::ToggleState KviTalCheckListItem::storedState(KviTalCheckListItem *key) const + { + QHash::Iterator it = d->statesDict.find(key); + if (it != d->statesDict.end()) + return it.value(); + else + return Off; + } + + void KviTalCheckListItem::turnOffChild() + { + if (myType == RadioButtonController && d->exclusive) + d->exclusive->setOn(false); + } + + void KviTalCheckListItem::activate() + { + KviTalListView * lv = listView(); + + if (lv && !lv->isEnabled() || !isEnabled()) + return; + + QPoint pos; + int boxsize = lv->style()->pixelMetric(QStyle::PM_CheckListButtonSize, 0, lv); + if (activatedPos(pos)) { + bool parentControl = false; + if (parent() && parent()->rtti() == 1 && + ((KviTalCheckListItem*) parent())->type() == RadioButtonController) + parentControl = true; + + int x = parentControl ? 0 : 3; + int align = lv->columnAlignment(0); + int marg = lv->itemMargin(); + int y = 0; + + if (align & Qt::AlignVCenter) + y = ((height() - boxsize) / 2) + marg; + else + y = (lv->fontMetrics().height() + 2 + marg - boxsize) / 2; + + QRect r(x, y, boxsize-3, boxsize-3); + // columns might have been swapped + r.moveBy(lv->header()->sectionPos(0), 0); + if (!r.contains(pos)) + return; + } + if ((myType == CheckBox) || (myType == CheckBoxController)) { + //lv->d->startEdit = FALSE; + switch (internalState()) { + case On: + setState(Off); + break; + case Off: + if (!isTristate() && myType == CheckBox) { + setState(On); + } else { + setState(NoChange); + if (myType == CheckBoxController && internalState() != NoChange) + setState(On); + } + break; + case NoChange: + setState(On); + break; + } + ignoreDoubleClick(); + } else if (myType == RadioButton) { + setOn(true); + ignoreDoubleClick(); + } + } + + void KviTalCheckListItem::setOn(bool b ) + { + if (b) + setState(On , true, true); + else + setState(Off , true, true); + } + + void KviTalCheckListItem::stateChange(bool) + { + } + + void KviTalCheckListItem::stateChange(ToggleState s) + { + stateChange(s == On); + } + + void KviTalCheckListItem::restoreState(KviTalCheckListItem *key, int depth) + { + switch (type()) { + case CheckBox: + setCurrentState(storedState(key)); + stateChange(state()); + repaint(); + break; + case CheckBoxController: { + KviTalListViewItem *item = firstChild(); + int childCount = 0; + while (item) { + // recursively calling restoreState for children of type CheckBox and CheckBoxController + if (item->rtti() == 1 && + (((KviTalCheckListItem*)item)->type() == CheckBox || + ((KviTalCheckListItem*)item)->type() == CheckBoxController)) { + ((KviTalCheckListItem*)item)->restoreState(key , depth+1); + childCount++; + } + item = item->nextSibling(); + } + if (childCount > 0) { + if (depth == 0) + updateController(true); + else + updateController(false); + } else { + // if there are no children we retrieve the CheckBoxController state directly. + setState(storedState(key), true, false); + } + } + break; + default: + break; + } + } + + void KviTalCheckListItem::updateController(bool update , bool store) + { + if (myType != CheckBoxController) + return; + + KviTalCheckListItem *controller = 0; + // checks if this CheckBoxController has another CheckBoxController as parent + if (parent() && parent()->rtti() == 1 + && ((KviTalCheckListItem*)parent())->type() == CheckBoxController) + controller = (KviTalCheckListItem*)parent(); + + ToggleState theState = Off; + bool first = true; + KviTalListViewItem *item = firstChild(); + while(item && theState != NoChange) { + if (item->rtti() == 1 && + (((KviTalCheckListItem*)item)->type() == CheckBox || + ((KviTalCheckListItem*)item)->type() == CheckBoxController)) { + KviTalCheckListItem *checkItem = (KviTalCheckListItem*)item; + if (first) { + theState = checkItem->internalState(); + first = false; + } else { + if (checkItem->internalState() == NoChange || + theState != checkItem->internalState()) + theState = NoChange; + else + theState = checkItem->internalState(); + } + } + item = item->nextSibling(); + } + if (internalState() != theState) { + setCurrentState(theState); + if (store && (internalState() == On || internalState() == Off)) + updateStoredState(this); + stateChange(state()); + if (update && controller) { + controller->updateController(update, store); + } + repaint(); + } + } + + void KviTalCheckListItem::updateStoredState(KviTalCheckListItem *key) + { + if (myType != CheckBoxController) + return; + + KviTalListViewItem *item = firstChild(); + while(item) { + if (item->rtti() == 1) { + KviTalCheckListItem *checkItem = (KviTalCheckListItem*)item; + if (checkItem->type() == CheckBox) + checkItem->setStoredState(checkItem->internalState(), key); + else if (checkItem->type() == CheckBoxController) + checkItem->updateStoredState(key); + } + item = item->nextSibling(); + } + // this state is only needed if the CheckBoxController has no CheckBox / CheckBoxController children. + setStoredState(internalState() , key); + } + + void KviTalCheckListItem::setup() + { + KviTalListViewItem::setup(); + int h = height(); + KviTalListView *lv = listView(); + if (lv) + h = qMax(lv->style()->pixelMetric(QStyle::PM_CheckListButtonSize, 0, lv), + h); + h = qMax(h, QApplication::globalStrut().height()); + setHeight(h); + } + + int KviTalCheckListItem::width(const QFontMetrics& fm, const KviTalListView* lv, int column) const + { + int r = KviTalListViewItem::width(fm, lv, column); + if (column == 0) { + r += lv->itemMargin(); + if (myType == RadioButtonController && pixmap(0)) { + // r += 0; + } else { + r += lv->style()->pixelMetric(QStyle::PM_CheckListButtonSize, 0, lv) + 4; + } + } + return qMax(r, QApplication::globalStrut().width()); + } + + void KviTalCheckListItem::paintCell(QPainter * p, const QColorGroup & cg, + int column, int width, int align) + { + if (!p) + return; + + KviTalListView *lv = listView(); + if (!lv) + return; + + const QPalette::ColorRole crole = lv->foregroundRole(); + if (cg.brush(crole) != lv->palette().brush(crole)) + p->fillRect(0, 0, width, height(), cg.brush(crole)); + else + lv->paintEmptyArea(p, QRect(0, 0, width, height())); + + if (column != 0) { + // The rest is text, or for subclasses to change. + KviTalListViewItem::paintCell(p, cg, column, width, align); + return; + } + + bool parentControl = false; + if (parent() && parent()->rtti() == 1 && + ((KviTalCheckListItem*) parent())->type() == RadioButtonController) + parentControl = true; + + QFontMetrics fm(lv->fontMetrics()); + int boxsize = lv->style()->pixelMetric(myType == RadioButtonController ? QStyle::PM_CheckListControllerSize : + QStyle::PM_CheckListButtonSize, 0, lv); + int marg = lv->itemMargin(); + int r = marg; + + // Draw controller / checkbox / radiobutton --------------------- + QStyle::State styleflags = QStyle::State_None; + if (internalState() == On) { + styleflags |= QStyle::State_On; + } else if (internalState() == NoChange) { + if (myType == CheckBoxController && !isTristate()) + styleflags |= QStyle::State_Off; + else + styleflags |= QStyle::State_NoChange; + } else { + styleflags |= QStyle::State_Off; + } + if (isSelected()) + styleflags |= QStyle::State_Selected; + if (isEnabled() && lv->isEnabled()) + styleflags |= QStyle::State_Enabled; + if (lv->window()->isActiveWindow()) + styleflags |= QStyle::State_Active; + + if (myType == RadioButtonController) { + int x = 0; + if(!parentControl) + x += 3; + if (!pixmap(0)) { + QStyleOptionQ3ListView opt = getStyleOption(lv, this); + opt.rect.setRect(x, 0, boxsize, fm.height() + 2 + marg); + opt.palette = cg; + opt.state = styleflags; + lv->style()->drawPrimitive(QStyle::PE_Q3CheckListController, &opt, p, lv); + r += boxsize + 4; + } + } else { + Q_ASSERT(lv); //### + int x = 0; + int y = 0; + if (!parentControl) + x += 3; + if (align & Qt::AlignVCenter) + y = ((height() - boxsize) / 2) + marg; + else + y = (fm.height() + 2 + marg - boxsize) / 2; + + QStyleOptionQ3ListView opt = getStyleOption(lv, this); + opt.rect.setRect(x, y, boxsize, fm.height() + 2 + marg); + opt.palette = cg; + opt.state = styleflags; + lv->style()->drawPrimitive((myType == CheckBox || myType == CheckBoxController) + ? QStyle::PE_Q3CheckListIndicator + : QStyle::PE_Q3CheckListExclusiveIndicator, &opt, p, lv); + r += boxsize + 4; + } + + // Draw text ---------------------------------------------------- + p->translate(r, 0); + p->setPen(QPen(cg.text())); + KviTalListViewItem::paintCell(p, cg, column, width - r, align); + } + + void KviTalCheckListItem::paintFocus(QPainter *p, const QColorGroup & cg, + const QRect & r) + { + bool intersect = true; + KviTalListView *lv = listView(); + if (lv && lv->header()->mapToActual(0) != 0) { + int xdepth = lv->treeStepSize() * (depth() + (lv->rootIsDecorated() ? 1 : 0)) + lv->itemMargin(); + int p = lv->header()->cellPos(lv->header()->mapToActual(0)); + xdepth += p; + intersect = r.intersects(QRect(p, r.y(), xdepth - p + 1, r.height())); + } + bool parentControl = false; + if (parent() && parent()->rtti() == 1 && + ((KviTalCheckListItem*) parent())->type() == RadioButtonController) + parentControl = true; + if (myType != RadioButtonController && intersect && + (lv->rootIsDecorated() || myType == RadioButton || + (myType == CheckBox && parentControl))) { + QRect rect; + int boxsize = lv->style()->pixelMetric(QStyle::PM_CheckListButtonSize, 0, lv); + if (lv->columnAlignment(0) == Qt::AlignCenter) { + QFontMetrics fm(lv->font()); + int bx = (lv->columnWidth(0) - (boxsize + fm.width(text())))/2 + boxsize; + if (bx < 0) bx = 0; + rect.setRect(r.x() + bx + 5, r.y(), r.width() - bx - 5, + r.height()); + } else + rect.setRect(r.x() + boxsize + 5, r.y(), r.width() - boxsize - 5, + r.height()); + KviTalListViewItem::paintFocus(p, cg, rect); + } else { + KviTalListViewItem::paintFocus(p, cg, r); + } + } + + + #include "kvi_tal_listview_qt4.moc" +#else + #include + #include + #include + #include + + KviTalListView::KviTalListView(QWidget * pParent) + : QListView(pParent) + { + connect(this,SIGNAL(selectionChanged(QListViewItem *)),this,SLOT(redirect_selectionChanged(QListViewItem *))); + connect(this,SIGNAL(currentChanged(QListViewItem *)),this,SLOT(redirect_currentChanged(QListViewItem *))); + connect(this,SIGNAL(clicked(QListViewItem *)),this,SLOT(redirect_clicked(QListViewItem *))); + connect(this,SIGNAL(clicked(QListViewItem *,const QPoint &,int)),this,SLOT(redirect_clicked(QListViewItem *,const QPoint &,int))); + connect(this,SIGNAL(pressed(QListViewItem *)),this,SLOT(redirect_pressed(QListViewItem *))); + connect(this,SIGNAL(pressed(QListViewItem *,const QPoint &,int)),this,SLOT(redirect_pressed(QListViewItem *,const QPoint &,int))); + connect(this,SIGNAL(doubleClicked(QListViewItem *)),this,SLOT(redirect_doubleClicked(QListViewItem *))); + connect(this,SIGNAL(doubleClicked(QListViewItem *,const QPoint &,int)),this,SLOT(redirect_doubleClicked(QListViewItem *,const QPoint &,int))); + connect(this,SIGNAL(returnPressed(QListViewItem *)),this,SLOT(redirect_returnPressed(QListViewItem *))); + connect(this,SIGNAL(spacePressed(QListViewItem *)),this,SLOT(redirect_spacePressed(QListViewItem *))); + connect(this,SIGNAL(rightButtonClicked(QListViewItem *,const QPoint &,int)),this,SLOT(redirect_rightButtonClicked(QListViewItem *,const QPoint &,int))); + connect(this,SIGNAL(rightButtonPressed(QListViewItem *,const QPoint &,int)),this,SLOT(redirect_rightButtonPressed(QListViewItem *,const QPoint &,int))); + connect(this,SIGNAL(mouseButtonClicked(int,QListViewItem *,const QPoint &,int)),this,SLOT(redirect_mouseButtonClicked(int,QListViewItem *,const QPoint &,int))); + connect(this,SIGNAL(mouseButtonPressed(int,QListViewItem *,const QPoint &,int)),this,SLOT(redirect_mouseButtonPressed(int,QListViewItem *,const QPoint &,int))); + connect(this,SIGNAL(contextMenuRequested(QListViewItem *,const QPoint &,int)),this,SLOT(redirect_contextMenuRequested(QListViewItem *,const QPoint &,int))); + connect(this,SIGNAL(onItem(QListViewItem *)),this,SLOT(redirect_onItem(QListViewItem *))); + connect(this,SIGNAL(expanded(QListViewItem *)),this,SLOT(redirect_expanded(QListViewItem *))); + connect(this,SIGNAL(collapsed(QListViewItem *)),this,SLOT(redirect_collapsed(QListViewItem *))); + } + + void KviTalListView::redirect_selectionChanged(QListViewItem * pItem) + { + emit selectionChanged((KviTalListViewItem *)pItem); + } + + void KviTalListView::redirect_currentChanged(QListViewItem * pItem) + { + emit currentChanged((KviTalListViewItem *)pItem); + } + + void KviTalListView::redirect_clicked(QListViewItem * pItem) + { + emit clicked((KviTalListViewItem *)pItem); + } + + void KviTalListView::redirect_clicked(QListViewItem * pItem,const QPoint &pnt,int uColumn) + { + emit clicked((KviTalListViewItem *)pItem,pnt,uColumn); + } + + void KviTalListView::redirect_pressed(QListViewItem * pItem) + { + emit pressed((KviTalListViewItem *)pItem); + } + + void KviTalListView::redirect_pressed(QListViewItem * pItem,const QPoint &pnt,int uColumn) + { + emit pressed((KviTalListViewItem *)pItem,pnt,uColumn); + } + + void KviTalListView::redirect_doubleClicked(QListViewItem * pItem) + { + emit doubleClicked((KviTalListViewItem *)pItem); + } + + void KviTalListView::redirect_doubleClicked(QListViewItem * pItem,const QPoint &pnt,int uColumn) + { + emit doubleClicked((KviTalListViewItem *)pItem,pnt,uColumn); + } + + void KviTalListView::redirect_returnPressed(QListViewItem * pItem) + { + emit returnPressed((KviTalListViewItem *)pItem); + } + + void KviTalListView::redirect_spacePressed(QListViewItem * pItem) + { + emit spacePressed((KviTalListViewItem *)pItem); + } + + void KviTalListView::redirect_rightButtonClicked(QListViewItem * pItem,const QPoint &pnt,int uColumn) + { + emit rightButtonClicked((KviTalListViewItem *)pItem,pnt,uColumn); + } + + void KviTalListView::redirect_rightButtonPressed(QListViewItem * pItem,const QPoint &pnt,int uColumn) + { + emit rightButtonPressed((KviTalListViewItem *)pItem,pnt,uColumn); + } + + void KviTalListView::redirect_mouseButtonClicked(int iButton,QListViewItem * pItem,const QPoint &pnt,int uColumn) + { + emit mouseButtonClicked(iButton,(KviTalListViewItem *)pItem,pnt,uColumn); + } + + void KviTalListView::redirect_mouseButtonPressed(int iButton,QListViewItem * pItem,const QPoint &pnt,int uColumn) + { + emit mouseButtonPressed(iButton,(KviTalListViewItem *)pItem,pnt,uColumn); + } + + void KviTalListView::redirect_contextMenuRequested(QListViewItem * pItem,const QPoint &pnt,int uColumn) + { + emit contextMenuRequested((KviTalListViewItem *)pItem,pnt,uColumn); + } + + void KviTalListView::redirect_onItem(QListViewItem * pItem) + { + emit onItem((KviTalListViewItem *)pItem); + } + + void KviTalListView::redirect_expanded(QListViewItem * pItem) + { + emit expanded((KviTalListViewItem *)pItem); + } + + void KviTalListView::redirect_collapsed(QListViewItem * pItem) + { + emit collapsed((KviTalListViewItem *)pItem); + } + + struct KviTalCheckListItemPrivate + { + KviTalCheckListItemPrivate(): + exclusive( 0 ), + currentState( KviTalCheckListItem::Off ), + statesDict( 0 ), + tristate( FALSE ) {} + + KviTalCheckListItem *exclusive; + KviTalCheckListItem::ToggleState currentState; + KviPointerHashTable *statesDict; + bool tristate; + }; + + // ### obscenity is warranted. + + KviTalCheckListItem::KviTalCheckListItem( KviTalCheckListItem *parent, const QString &text, + Type tt ) + : KviTalListViewItem( parent, text, QString::null ) + { + myType = tt; + init(); + if ( myType == RadioButton ) { + if ( parent->type() != RadioButtonController ) + qWarning( "KviTalCheckListItem::KviTalCheckListItem(), radio button must be " + "child of a controller" ); + else + d->exclusive = parent; + } + } + + KviTalCheckListItem::KviTalCheckListItem( KviTalCheckListItem *parent, KviTalListViewItem *after, + const QString &text, Type tt ) + : KviTalListViewItem( parent, after, text ) + { + myType = tt; + init(); + if ( myType == RadioButton ) { + if ( parent->type() != RadioButtonController ) + qWarning( "KviTalCheckListItem::KviTalCheckListItem(), radio button must be " + "child of a controller" ); + else + d->exclusive = parent; + } + } + + KviTalCheckListItem::KviTalCheckListItem( KviTalListViewItem *parent, const QString &text, + Type tt ) + : KviTalListViewItem( parent, text, QString::null ) + { + myType = tt; + if ( myType == RadioButton ) { + qWarning( "KviTalCheckListItem::KviTalCheckListItem(), radio button must be " + "child of a KviTalCheckListItem" ); + } + init(); + } + + KviTalCheckListItem::KviTalCheckListItem( KviTalListViewItem *parent, KviTalListViewItem *after, + const QString &text, Type tt ) + : KviTalListViewItem( parent, after, text ) + { + myType = tt; + if ( myType == RadioButton ) { + qWarning( "KviTalCheckListItem::KviTalCheckListItem(), radio button must be " + "child of a KviTalCheckListItem" ); + } + init(); + } + + KviTalCheckListItem::KviTalCheckListItem( KviTalListView *parent, const QString &text, + Type tt ) + : KviTalListViewItem( parent, text ) + { + myType = tt; + if ( tt == RadioButton ) + qWarning( "KviTalCheckListItem::KviTalCheckListItem(), radio button must be " + "child of a KviTalCheckListItem" ); + init(); + } + + KviTalCheckListItem::KviTalCheckListItem( KviTalListView *parent, KviTalListViewItem *after, + const QString &text, Type tt ) + : KviTalListViewItem( parent, after, text ) + { + myType = tt; + if ( tt == RadioButton ) + qWarning( "KviTalCheckListItem::KviTalCheckListItem(), radio button must be " + "child of a KviTalCheckListItem" ); + init(); + } + + + int KviTalCheckListItem::RTTI = 1; + + int KviTalCheckListItem::rtti() const + { + return RTTI; + } + + KviTalCheckListItem::KviTalCheckListItem( KviTalListView *parent, const QString &text, + const QPixmap & p ) + : KviTalListViewItem( parent, text ) + { + myType = RadioButtonController; + setPixmap( 0, p ); + init(); + } + + KviTalCheckListItem::KviTalCheckListItem( KviTalListViewItem *parent, const QString &text, + const QPixmap & p ) + : KviTalListViewItem( parent, text ) + { + myType = RadioButtonController; + setPixmap( 0, p ); + init(); + } + + void KviTalCheckListItem::init() + { + d = new KviTalCheckListItemPrivate(); + on = FALSE; // ### remove on ver 4 + if ( myType == CheckBoxController || myType == CheckBox ) { + d->statesDict = new KviPointerHashTable(101); + d->statesDict->setAutoDelete( TRUE ); + } + // CheckBoxControllers by default have tristate set to TRUE + if ( myType == CheckBoxController ) + setTristate( TRUE ); + } + + KviTalCheckListItem::~KviTalCheckListItem() + { + if ( myType == RadioButton + && d->exclusive && d->exclusive->d + && d->exclusive->d->exclusive == this ) + d->exclusive->turnOffChild(); + d->exclusive = 0; // so the children won't try to access us. + if ( d->statesDict ) + delete d->statesDict; + delete d; + d = 0; + } + + void KviTalCheckListItem::setTristate( bool b ) + { + if ( ( myType != CheckBoxController ) && ( myType != CheckBox ) ) { + qWarning( "KviTalCheckListItem::setTristate(), has no effect on RadioButton " + "or RadioButtonController." ); + return; + } + d->tristate = b; + } + + bool KviTalCheckListItem::isTristate() const + { + return d->tristate; + } + + KviTalCheckListItem::ToggleState KviTalCheckListItem::state() const + { + if ( !isTristate() && internalState() == NoChange ) + return Off; + else + return d->currentState; + } + + KviTalCheckListItem::ToggleState KviTalCheckListItem::internalState() const + { + return d->currentState; + } + + void KviTalCheckListItem::setState( ToggleState s ) + { + if ( myType == CheckBoxController && state() == NoChange ) + updateStoredState( (void*) this ); + setState( s, TRUE, TRUE ); + } + + void KviTalCheckListItem::setState( ToggleState s, bool update, bool store) + { + + if ( s == internalState() ) + return; + + if ( myType == CheckBox ) { + setCurrentState( s ); + stateChange( state() ); + if ( update && parent() && parent()->rtti() == 1 + && ((KviTalCheckListItem*)parent())->type() == CheckBoxController ) + ((KviTalCheckListItem*)parent())->updateController( update, store ); + } else if ( myType == CheckBoxController ) { + if ( s == NoChange && childCount()) { + restoreState( (void*) this ); + } else { + KviTalListViewItem *item = firstChild(); + int childCount = 0; + while( item ) { + if ( item->rtti() == 1 && + ( ((KviTalCheckListItem*)item)->type() == CheckBox || + ((KviTalCheckListItem*)item)->type() == CheckBoxController ) ) { + KviTalCheckListItem *checkItem = (KviTalCheckListItem*)item; + checkItem->setState( s, FALSE, FALSE ); + childCount++; + } + item = item->nextSibling(); + } + if ( update ) { + if ( childCount > 0 ) { + ToggleState oldState = internalState(); + updateController( FALSE, FALSE ); + if ( oldState != internalState() && + parent() && parent()->rtti() == 1 && + ((KviTalCheckListItem*)parent())->type() == CheckBoxController ) + ((KviTalCheckListItem*)parent())->updateController( update, store ); + + updateController( update, store ); + } else { + // if there are no children we simply set the CheckBoxController and update its parent + setCurrentState( s ); + stateChange( state() ); + if ( parent() && parent()->rtti() == 1 + && ((KviTalCheckListItem*)parent())->type() == CheckBoxController ) + ((KviTalCheckListItem*)parent())->updateController( update, store ); + } + } else { + setCurrentState( s ); + stateChange( state() ); + } + + } + } else if ( myType == RadioButton ) { + if ( s == On ) { + if ( d->exclusive && d->exclusive->d->exclusive != this ) + d->exclusive->turnOffChild(); + setCurrentState( s ); + if ( d->exclusive ) + d->exclusive->d->exclusive = this; + } else { + if ( d->exclusive && d->exclusive->d->exclusive == this ) + d->exclusive->d->exclusive = 0; + setCurrentState( Off ); + } + stateChange( state() ); + } + repaint(); + } + + void KviTalCheckListItem::setCurrentState( ToggleState s ) + { + ToggleState old = d->currentState; + d->currentState = s; + if (d->currentState == On) + on = TRUE; + else + on = FALSE; + + #if defined(QT_ACCESSIBILITY_SUPPORT) + if ( old != d->currentState && listView() ) + QAccessible::updateAccessibility( listView()->viewport(), indexOfItem( this ), QAccessible::StateChanged ); + #else + Q_UNUSED( old ); + #endif + } + + void KviTalCheckListItem::setStoredState( ToggleState newState, void *key ) + { + if ( myType == CheckBox || myType == CheckBoxController ) + d->statesDict->replace( key, new ToggleState(newState) ); + } + + KviTalCheckListItem::ToggleState KviTalCheckListItem::storedState( void *key ) const + { + if ( !d->statesDict ) + return Off; + + ToggleState *foundState = d->statesDict->find( key ); + if ( foundState ) + return ToggleState( *foundState ); + else + return Off; + } + + void KviTalCheckListItem::turnOffChild() + { + if ( myType == RadioButtonController && d->exclusive ) + d->exclusive->setOn( FALSE ); + } + + void KviTalCheckListItem::activate() + { + KviTalListView * lv = listView(); + + if ( lv && !lv->isEnabled() || !isEnabled() ) + return; + + QPoint pos; + int boxsize = lv->style().pixelMetric(QStyle::PM_CheckListButtonSize, lv); + if ( activatedPos( pos ) ) { + bool parentControl = FALSE; + if ( parent() && parent()->rtti() == 1 && + ((KviTalCheckListItem*) parent())->type() == RadioButtonController ) + parentControl = TRUE; + + int x = parentControl ? 0 : 3; + int align = lv->columnAlignment( 0 ); + int marg = lv->itemMargin(); + int y = 0; + + if ( align & AlignVCenter ) + y = ( ( height() - boxsize ) / 2 ) + marg; + else + y = (lv->fontMetrics().height() + 2 + marg - boxsize) / 2; + + QRect r( x, y, boxsize-3, boxsize-3 ); + // columns might have been swapped + r.moveBy( lv->header()->sectionPos( 0 ), 0 ); + if ( !r.contains( pos ) ) + return; + } + if ( ( myType == CheckBox ) || ( myType == CheckBoxController) ) { + switch ( internalState() ) { + case On: + setState( Off ); + break; + case Off: + if ( !isTristate() && myType == CheckBox ) { + setState( On ); + } else { + setState( NoChange ); + if ( myType == CheckBoxController && internalState() != NoChange ) + setState( On ); + } + break; + case NoChange: + setState( On ); + break; + } + ignoreDoubleClick(); + } else if ( myType == RadioButton ) { + setOn( TRUE ); + ignoreDoubleClick(); + } + } + + void KviTalCheckListItem::setOn( bool b ) + { + if ( b ) + setState( On , TRUE, TRUE ); + else + setState( Off , TRUE, TRUE ); + } + + void KviTalCheckListItem::stateChange( bool ) + { + } + + void KviTalCheckListItem::stateChange( ToggleState s ) + { + stateChange( s == On ); + } + + void KviTalCheckListItem::restoreState( void *key, int depth ) + { + switch ( type() ) { + case CheckBox: + setCurrentState( storedState( key ) ); + stateChange( state() ); + repaint(); + break; + case CheckBoxController: { + KviTalListViewItem *item = firstChild(); + int childCount = 0; + while ( item ) { + // recursively calling restoreState for children of type CheckBox and CheckBoxController + if ( item->rtti() == 1 && + ( ((KviTalCheckListItem*)item)->type() == CheckBox || + ((KviTalCheckListItem*)item)->type() == CheckBoxController ) ) { + ((KviTalCheckListItem*)item)->restoreState( key , depth+1 ); + childCount++; + } + item = item->nextSibling(); + } + if ( childCount > 0 ) { + if ( depth == 0 ) + updateController( TRUE ); + else + updateController( FALSE ); + } else { + // if there are no children we retrieve the CheckBoxController state directly. + setState( storedState( key ), TRUE, FALSE ); + } + } + break; + default: + break; + } + } + + void KviTalCheckListItem::updateController( bool update , bool store ) + { + if ( myType != CheckBoxController ) + return; + + KviTalCheckListItem *controller = 0; + // checks if this CheckBoxController has another CheckBoxController as parent + if ( parent() && parent()->rtti() == 1 + && ((KviTalCheckListItem*)parent())->type() == CheckBoxController ) + controller = (KviTalCheckListItem*)parent(); + + ToggleState theState = Off; + bool first = TRUE; + KviTalListViewItem *item = firstChild(); + while( item && theState != NoChange ) { + if ( item->rtti() == 1 && + ( ((KviTalCheckListItem*)item)->type() == CheckBox || + ((KviTalCheckListItem*)item)->type() == CheckBoxController ) ) { + KviTalCheckListItem *checkItem = (KviTalCheckListItem*)item; + if ( first ) { + theState = checkItem->internalState(); + first = FALSE; + } else { + if ( checkItem->internalState() == NoChange || + theState != checkItem->internalState() ) + theState = NoChange; + else + theState = checkItem->internalState(); + } + } + item = item->nextSibling(); + } + if ( internalState() != theState ) { + setCurrentState( theState ); + if ( store && ( internalState() == On || internalState() == Off ) ) + updateStoredState( (void*) this ); + stateChange( state() ); + if ( update && controller ) { + controller->updateController( update, store ); + } + repaint(); + } + } + + void KviTalCheckListItem::updateStoredState( void *key ) + { + if ( myType != CheckBoxController ) + return; + + KviTalListViewItem *item = firstChild(); + while( item ) { + if ( item->rtti() == 1 ) { + KviTalCheckListItem *checkItem = (KviTalCheckListItem*)item; + if ( checkItem->type() == CheckBox ) + checkItem->setStoredState( checkItem->internalState(), key ); + else if (checkItem->type() == CheckBoxController ) + checkItem->updateStoredState( key ); + } + item = item->nextSibling(); + } + // this state is only needed if the CheckBoxController has no CheckBox / CheckBoxController children. + setStoredState( internalState() , key ); + } + + void KviTalCheckListItem::setup() + { + KviTalListViewItem::setup(); + int h = height(); + KviTalListView *lv = listView(); + if ( lv ) + h = QMAX( lv->style().pixelMetric(QStyle::PM_CheckListButtonSize, lv), + h ); + h = QMAX( h, QApplication::globalStrut().height() ); + setHeight( h ); + } + + int KviTalCheckListItem::width( const QFontMetrics& fm, const KviTalListView* lv, int column) const + { + int r = KviTalListViewItem::width( fm, lv, column ); + if ( column == 0 ) { + r += lv->itemMargin(); + if ( myType == RadioButtonController && pixmap( 0 ) ) { + // r += 0; + } else { + r += lv->style().pixelMetric(QStyle::PM_CheckListButtonSize, lv) + 4; + } + } + return QMAX( r, QApplication::globalStrut().width() ); + } + + void KviTalCheckListItem::paintCell( QPainter * p, const QColorGroup & cg, + int column, int width, int align ) + { + if ( !p ) + return; + + KviTalListView *lv = listView(); + if ( !lv ) + return; + + const BackgroundMode bgmode = lv->viewport()->backgroundMode(); + const QColorGroup::ColorRole crole = QPalette::backgroundRoleFromMode( bgmode ); + if ( cg.brush( crole ) != lv->colorGroup().brush( crole ) ) + p->fillRect( 0, 0, width, height(), cg.brush( crole ) ); + else + lv->paintEmptyArea( p, QRect( 0, 0, width, height() ) ); + + if ( column != 0 ) { + // The rest is text, or for subclasses to change. + KviTalListViewItem::paintCell( p, cg, column, width, align ); + return; + } + + bool parentControl = FALSE; + if ( parent() && parent()->rtti() == 1 && + ((KviTalCheckListItem*) parent())->type() == RadioButtonController ) + parentControl = TRUE; + + QFontMetrics fm( lv->fontMetrics() ); + int boxsize = lv->style().pixelMetric( myType == RadioButtonController ? QStyle::PM_CheckListControllerSize : + QStyle::PM_CheckListButtonSize, lv); + int marg = lv->itemMargin(); + int r = marg; + + // Draw controller / checkbox / radiobutton --------------------- + int styleflags = QStyle::Style_Default; + if ( internalState() == On ) { + styleflags |= QStyle::Style_On; + } else if ( internalState() == NoChange ) { + if ( myType == CheckBoxController && !isTristate() ) + styleflags |= QStyle::Style_Off; + else + styleflags |= QStyle::Style_NoChange; + } else { + styleflags |= QStyle::Style_Off; + } + if ( isSelected() ) + styleflags |= QStyle::Style_Selected; + if ( isEnabled() && lv->isEnabled() ) + styleflags |= QStyle::Style_Enabled; + + if ( myType == RadioButtonController ) { + int x = 0; + if(!parentControl) + x += 3; + if ( !pixmap( 0 ) ) { + lv->style().drawPrimitive(QStyle::PE_CheckListController, p, + QRect(x, 0, boxsize, + fm.height() + 2 + marg), + cg, styleflags, QStyleOption(this)); + r += boxsize + 4; + } + } else { + Q_ASSERT( lv ); //### + int x = 0; + int y = 0; + if ( !parentControl ) + x += 3; + if ( align & AlignVCenter ) + y = ( ( height() - boxsize ) / 2 ) + marg; + else + y = (fm.height() + 2 + marg - boxsize) / 2; + + if ( ( myType == CheckBox ) || ( myType == CheckBoxController ) ) { + lv->style().drawPrimitive(QStyle::PE_CheckListIndicator, p, + QRect(x, y, boxsize, + fm.height() + 2 + marg), + cg, styleflags, QStyleOption(this)); + } else { //radio button look + lv->style().drawPrimitive(QStyle::PE_CheckListExclusiveIndicator, + p, QRect(x, y, boxsize, + fm.height() + 2 + marg), + cg, styleflags, QStyleOption(this)); + } + r += boxsize + 4; + } + + // Draw text ---------------------------------------------------- + p->translate( r, 0 ); + p->setPen( QPen( cg.text() ) ); + KviTalListViewItem::paintCell( p, cg, column, width - r, align ); + } + + void KviTalCheckListItem::paintFocus( QPainter *p, const QColorGroup & cg,const QRect & r ) + { + bool intersect = TRUE; + KviTalListView *lv = listView(); + if ( lv && lv->header()->mapToActual( 0 ) != 0 ) { + int xdepth = lv->treeStepSize() * ( depth() + ( lv->rootIsDecorated() ? 1 : 0) ) + lv->itemMargin(); + int p = lv->header()->cellPos( lv->header()->mapToActual( 0 ) ); + xdepth += p; + intersect = r.intersects( QRect( p, r.y(), xdepth - p + 1, r.height() ) ); + } + bool parentControl = FALSE; + if ( parent() && parent()->rtti() == 1 && + ((KviTalCheckListItem*) parent())->type() == RadioButtonController ) + parentControl = TRUE; + if ( myType != RadioButtonController && intersect && + (lv->rootIsDecorated() || myType == RadioButton || + (myType == CheckBox && parentControl) ) ) { + QRect rect; + int boxsize = lv->style().pixelMetric(QStyle::PM_CheckListButtonSize, lv); + if ( lv->columnAlignment(0) == AlignCenter ) { + QFontMetrics fm( lv->font() ); + int bx = (lv->columnWidth(0) - (boxsize + fm.width(text())))/2 + boxsize; + if ( bx < 0 ) bx = 0; + rect.setRect( r.x() + bx + 5, r.y(), r.width() - bx - 5, + r.height() ); + } else + rect.setRect( r.x() + boxsize + 5, r.y(), r.width() - boxsize - 5, + r.height() ); + KviTalListViewItem::paintFocus(p, cg, rect); + } else { + KviTalListViewItem::paintFocus(p, cg, r); + } + } + + #include "kvi_tal_listview_qt3.moc" +#endif + + + -- cgit v1.2.1