You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kvirc/src/kvilib/tal/kvi_tal_listview.cpp

1543 lines
52 KiB

//=============================================================================
//
// 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 <tqpainter.h>
#include <tqstyle.h>
#include <tq3header.h>
#include <tqapplication.h>
#include <tqhash.h>
#include <tqstyleoption.h>
#include <tqaccessible.h>
static TQStyleOptionQ3ListView getStyleOption(const Q3ListView *lv, const Q3ListViewItem *item)
{
TQStyleOptionQ3ListView opt;
opt.init(lv);
opt.subControls = TQStyle::SC_None;
opt.activeSubControls = TQStyle::SC_None;
TQWidget *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) {
TQStyleOptionQ3ListViewItem lvi;
lvi.height = item->height();
lvi.totalHeight = item->totalHeight();
lvi.itemY = item->itemPos();
lvi.childCount = item->childCount();
lvi.features = TQStyleOptionQ3ListViewItem::None;
lvi.state = TQStyle::State_None;
if (item->isEnabled())
lvi.state |= TQStyle::State_Enabled;
if (item->isOpen())
lvi.state |= TQStyle::State_Open;
if (item->isExpandable())
lvi.features |= TQStyleOptionQ3ListViewItem::Expandable;
if (item->multiLinesEnabled())
lvi.features |= TQStyleOptionQ3ListViewItem::MultiLine;
if (item->isVisible())
lvi.features |= TQStyleOptionQ3ListViewItem::Visible;
if (item->parent() && item->parent()->rtti() == 1
&& static_cast<Q3CheckListItem *>(item->parent())->type() == Q3CheckListItem::Controller)
lvi.features |= TQStyleOptionQ3ListViewItem::ParentControl;
opt.items.append(lvi);
if (!firstItem) {
item = item->nextSibling();
} else {
firstItem = false;
item = item->firstChild();
}
}
return opt;
}
KviTalListView::KviTalListView(TQWidget * pParent)
: Q3ListView(pParent)
{
connect(this,TQT_SIGNAL(selectionChanged(Q3ListViewItem *)),this,TQT_SLOT(redirect_selectionChanged(Q3ListViewItem *)));
connect(this,TQT_SIGNAL(currentChanged(Q3ListViewItem *)),this,TQT_SLOT(redirect_currentChanged(Q3ListViewItem *)));
connect(this,TQT_SIGNAL(clicked(Q3ListViewItem *)),this,TQT_SLOT(redirect_clicked(Q3ListViewItem *)));
connect(this,TQT_SIGNAL(clicked(Q3ListViewItem *,const TQPoint &,int)),this,TQT_SLOT(redirect_clicked(Q3ListViewItem *,const TQPoint &,int)));
connect(this,TQT_SIGNAL(pressed(Q3ListViewItem *)),this,TQT_SLOT(redirect_pressed(Q3ListViewItem *)));
connect(this,TQT_SIGNAL(pressed(Q3ListViewItem *,const TQPoint &,int)),this,TQT_SLOT(redirect_pressed(Q3ListViewItem *,const TQPoint &,int)));
connect(this,TQT_SIGNAL(doubleClicked(Q3ListViewItem *)),this,TQT_SLOT(redirect_doubleClicked(Q3ListViewItem *)));
connect(this,TQT_SIGNAL(doubleClicked(Q3ListViewItem *,const TQPoint &,int)),this,TQT_SLOT(redirect_doubleClicked(Q3ListViewItem *,const TQPoint &,int)));
connect(this,TQT_SIGNAL(returnPressed(Q3ListViewItem *)),this,TQT_SLOT(redirect_returnPressed(Q3ListViewItem *)));
connect(this,TQT_SIGNAL(spacePressed(Q3ListViewItem *)),this,TQT_SLOT(redirect_spacePressed(Q3ListViewItem *)));
connect(this,TQT_SIGNAL(rightButtonClicked(Q3ListViewItem *,const TQPoint &,int)),this,TQT_SLOT(redirect_rightButtonClicked(Q3ListViewItem *,const TQPoint &,int)));
connect(this,TQT_SIGNAL(rightButtonPressed(Q3ListViewItem *,const TQPoint &,int)),this,TQT_SLOT(redirect_rightButtonPressed(Q3ListViewItem *,const TQPoint &,int)));
connect(this,TQT_SIGNAL(mouseButtonClicked(int,Q3ListViewItem *,const TQPoint &,int)),this,TQT_SLOT(redirect_mouseButtonClicked(int,Q3ListViewItem *,const TQPoint &,int)));
connect(this,TQT_SIGNAL(mouseButtonPressed(int,Q3ListViewItem *,const TQPoint &,int)),this,TQT_SLOT(redirect_mouseButtonPressed(int,Q3ListViewItem *,const TQPoint &,int)));
connect(this,TQT_SIGNAL(contextMenuRequested(Q3ListViewItem *,const TQPoint &,int)),this,TQT_SLOT(redirect_contextMenuRequested(Q3ListViewItem *,const TQPoint &,int)));
connect(this,TQT_SIGNAL(onItem(Q3ListViewItem *)),this,TQT_SLOT(redirect_onItem(Q3ListViewItem *)));
connect(this,TQT_SIGNAL(expanded(Q3ListViewItem *)),this,TQT_SLOT(redirect_expanded(Q3ListViewItem *)));
connect(this,TQT_SIGNAL(collapsed(Q3ListViewItem *)),this,TQT_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 TQPoint &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 TQPoint &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 TQPoint &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 TQPoint &pnt,int uColumn)
{
emit rightButtonClicked((KviTalListViewItem *)pItem,pnt,uColumn);
}
void KviTalListView::redirect_rightButtonPressed(Q3ListViewItem * pItem,const TQPoint &pnt,int uColumn)
{
emit rightButtonPressed((KviTalListViewItem *)pItem,pnt,uColumn);
}
void KviTalListView::redirect_mouseButtonClicked(int iButton,Q3ListViewItem * pItem,const TQPoint &pnt,int uColumn)
{
emit mouseButtonClicked(iButton,(KviTalListViewItem *)pItem,pnt,uColumn);
}
void KviTalListView::redirect_mouseButtonPressed(int iButton,Q3ListViewItem * pItem,const TQPoint &pnt,int uColumn)
{
emit mouseButtonPressed(iButton,(KviTalListViewItem *)pItem,pnt,uColumn);
}
void KviTalListView::redirect_contextMenuRequested(Q3ListViewItem * pItem,const TQPoint &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;
TQHash<KviTalCheckListItem *, KviTalCheckListItem::ToggleState> statesDict;
bool tristate;
};
KviTalCheckListItem::KviTalCheckListItem(KviTalCheckListItem *parent, const TQString &text,
Type tt)
: KviTalListViewItem(parent, text, TQString())
{
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 TQString &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 TQString &text,
Type tt)
: KviTalListViewItem(parent, text, TQString())
{
myType = tt;
if (myType == RadioButton) {
qWarning("KviTalCheckListItem::KviTalCheckListItem(), radio button must be "
"child of a KviTalCheckListItem");
}
init();
}
KviTalCheckListItem::KviTalCheckListItem(KviTalListViewItem *parent, KviTalListViewItem *after,
const TQString &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 TQString &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 TQString &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 TQString &text,
const TQPixmap & p)
: KviTalListViewItem(parent, text)
{
myType = RadioButtonController;
setPixmap(0, p);
init();
}
KviTalCheckListItem::KviTalCheckListItem(KviTalListViewItem *parent, const TQString &text,
const TQPixmap & 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 tqchildren 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 tqchildren 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());
}
tqrepaint();
}
void KviTalCheckListItem::setCurrentState(ToggleState s)
{
ToggleState old = d->currentState;
d->currentState = s;
if (d->currentState == On)
on = true;
else
on = false;
//#ifndef TQT_NO_ACCESSIBILITY
// if (old != d->currentState && listView())
// TQAccessible::updateAccessibility(listView()->viewport(), indexOfItem(this), TQAccessible::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
{
TQHash<KviTalCheckListItem *, KviTalCheckListItem::ToggleState>::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;
TQPoint pos;
int boxsize = lv->tqstyle()->pixelMetric(TQStyle::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 & TQt::AlignVCenter)
y = ((height() - boxsize) / 2) + marg;
else
y = (lv->fontMetrics().height() + 2 + marg - boxsize) / 2;
TQRect 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());
tqrepaint();
break;
case CheckBoxController: {
KviTalListViewItem *item = firstChild();
int childCount = 0;
while (item) {
// recursively calling restoreState for tqchildren 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 tqchildren 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);
}
tqrepaint();
}
}
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 tqchildren.
setStoredState(internalState() , key);
}
void KviTalCheckListItem::setup()
{
KviTalListViewItem::setup();
int h = height();
KviTalListView *lv = listView();
if (lv)
h = qMax(lv->tqstyle()->pixelMetric(TQStyle::PM_CheckListButtonSize, 0, lv),
h);
h = qMax(h, TQApplication::globalStrut().height());
setHeight(h);
}
int KviTalCheckListItem::width(const TQFontMetrics& 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->tqstyle()->pixelMetric(TQStyle::PM_CheckListButtonSize, 0, lv) + 4;
}
}
return qMax(r, TQApplication::globalStrut().width());
}
void KviTalCheckListItem::paintCell(TQPainter * p, const TQColorGroup & cg,
int column, int width, int align)
{
if (!p)
return;
KviTalListView *lv = listView();
if (!lv)
return;
const TQPalette::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, TQRect(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;
TQFontMetrics fm(lv->fontMetrics());
int boxsize = lv->tqstyle()->pixelMetric(myType == RadioButtonController ? TQStyle::PM_CheckListControllerSize :
TQStyle::PM_CheckListButtonSize, 0, lv);
int marg = lv->itemMargin();
int r = marg;
// Draw controller / checkbox / radiobutton ---------------------
TQStyle::State styleflags = TQStyle::State_None;
if (internalState() == On) {
styleflags |= TQStyle::State_On;
} else if (internalState() == NoChange) {
if (myType == CheckBoxController && !isTristate())
styleflags |= TQStyle::State_Off;
else
styleflags |= TQStyle::State_NoChange;
} else {
styleflags |= TQStyle::State_Off;
}
if (isSelected())
styleflags |= TQStyle::State_Selected;
if (isEnabled() && lv->isEnabled())
styleflags |= TQStyle::State_Enabled;
if (lv->window()->isActiveWindow())
styleflags |= TQStyle::State_Active;
if (myType == RadioButtonController) {
int x = 0;
if(!parentControl)
x += 3;
if (!pixmap(0)) {
TQStyleOptionQ3ListView opt = getStyleOption(lv, this);
opt.rect.setRect(x, 0, boxsize, fm.height() + 2 + marg);
opt.palette = cg;
opt.state = styleflags;
lv->tqstyle()->drawPrimitive(TQStyle::PE_Q3CheckListController, &opt, p, lv);
r += boxsize + 4;
}
} else {
Q_ASSERT(lv); //###
int x = 0;
int y = 0;
if (!parentControl)
x += 3;
if (align & TQt::AlignVCenter)
y = ((height() - boxsize) / 2) + marg;
else
y = (fm.height() + 2 + marg - boxsize) / 2;
TQStyleOptionQ3ListView opt = getStyleOption(lv, this);
opt.rect.setRect(x, y, boxsize, fm.height() + 2 + marg);
opt.palette = cg;
opt.state = styleflags;
lv->tqstyle()->drawPrimitive((myType == CheckBox || myType == CheckBoxController)
? TQStyle::PE_Q3CheckListIndicator
: TQStyle::PE_Q3CheckListExclusiveIndicator, &opt, p, lv);
r += boxsize + 4;
}
// Draw text ----------------------------------------------------
p->translate(r, 0);
p->setPen(TQPen(cg.text()));
KviTalListViewItem::paintCell(p, cg, column, width - r, align);
}
void KviTalCheckListItem::paintFocus(TQPainter *p, const TQColorGroup & cg,
const TQRect & 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(TQRect(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))) {
TQRect rect;
int boxsize = lv->tqstyle()->pixelMetric(TQStyle::PM_CheckListButtonSize, 0, lv);
if (lv->columnAlignment(0) == TQt::AlignCenter) {
TQFontMetrics 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 <tqpainter.h>
#include <tqstyle.h>
#include <tqheader.h>
#include <tqapplication.h>
KviTalListView::KviTalListView(TQWidget * pParent)
: TQListView(pParent)
{
connect(this,TQT_SIGNAL(selectionChanged(TQListViewItem *)),this,TQT_SLOT(redirect_selectionChanged(TQListViewItem *)));
connect(this,TQT_SIGNAL(currentChanged(TQListViewItem *)),this,TQT_SLOT(redirect_currentChanged(TQListViewItem *)));
connect(this,TQT_SIGNAL(clicked(TQListViewItem *)),this,TQT_SLOT(redirect_clicked(TQListViewItem *)));
connect(this,TQT_SIGNAL(clicked(TQListViewItem *,const TQPoint &,int)),this,TQT_SLOT(redirect_clicked(TQListViewItem *,const TQPoint &,int)));
connect(this,TQT_SIGNAL(pressed(TQListViewItem *)),this,TQT_SLOT(redirect_pressed(TQListViewItem *)));
connect(this,TQT_SIGNAL(pressed(TQListViewItem *,const TQPoint &,int)),this,TQT_SLOT(redirect_pressed(TQListViewItem *,const TQPoint &,int)));
connect(this,TQT_SIGNAL(doubleClicked(TQListViewItem *)),this,TQT_SLOT(redirect_doubleClicked(TQListViewItem *)));
connect(this,TQT_SIGNAL(doubleClicked(TQListViewItem *,const TQPoint &,int)),this,TQT_SLOT(redirect_doubleClicked(TQListViewItem *,const TQPoint &,int)));
connect(this,TQT_SIGNAL(returnPressed(TQListViewItem *)),this,TQT_SLOT(redirect_returnPressed(TQListViewItem *)));
connect(this,TQT_SIGNAL(spacePressed(TQListViewItem *)),this,TQT_SLOT(redirect_spacePressed(TQListViewItem *)));
connect(this,TQT_SIGNAL(rightButtonClicked(TQListViewItem *,const TQPoint &,int)),this,TQT_SLOT(redirect_rightButtonClicked(TQListViewItem *,const TQPoint &,int)));
connect(this,TQT_SIGNAL(rightButtonPressed(TQListViewItem *,const TQPoint &,int)),this,TQT_SLOT(redirect_rightButtonPressed(TQListViewItem *,const TQPoint &,int)));
connect(this,TQT_SIGNAL(mouseButtonClicked(int,TQListViewItem *,const TQPoint &,int)),this,TQT_SLOT(redirect_mouseButtonClicked(int,TQListViewItem *,const TQPoint &,int)));
connect(this,TQT_SIGNAL(mouseButtonPressed(int,TQListViewItem *,const TQPoint &,int)),this,TQT_SLOT(redirect_mouseButtonPressed(int,TQListViewItem *,const TQPoint &,int)));
connect(this,TQT_SIGNAL(contextMenuRequested(TQListViewItem *,const TQPoint &,int)),this,TQT_SLOT(redirect_contextMenuRequested(TQListViewItem *,const TQPoint &,int)));
connect(this,TQT_SIGNAL(onItem(TQListViewItem *)),this,TQT_SLOT(redirect_onItem(TQListViewItem *)));
connect(this,TQT_SIGNAL(expanded(TQListViewItem *)),this,TQT_SLOT(redirect_expanded(TQListViewItem *)));
connect(this,TQT_SIGNAL(collapsed(TQListViewItem *)),this,TQT_SLOT(redirect_collapsed(TQListViewItem *)));
}
void KviTalListView::redirect_selectionChanged(TQListViewItem * pItem)
{
emit selectionChanged((KviTalListViewItem *)pItem);
}
void KviTalListView::redirect_currentChanged(TQListViewItem * pItem)
{
emit currentChanged((KviTalListViewItem *)pItem);
}
void KviTalListView::redirect_clicked(TQListViewItem * pItem)
{
emit clicked((KviTalListViewItem *)pItem);
}
void KviTalListView::redirect_clicked(TQListViewItem * pItem,const TQPoint &pnt,int uColumn)
{
emit clicked((KviTalListViewItem *)pItem,pnt,uColumn);
}
void KviTalListView::redirect_pressed(TQListViewItem * pItem)
{
emit pressed((KviTalListViewItem *)pItem);
}
void KviTalListView::redirect_pressed(TQListViewItem * pItem,const TQPoint &pnt,int uColumn)
{
emit pressed((KviTalListViewItem *)pItem,pnt,uColumn);
}
void KviTalListView::redirect_doubleClicked(TQListViewItem * pItem)
{
emit doubleClicked((KviTalListViewItem *)pItem);
}
void KviTalListView::redirect_doubleClicked(TQListViewItem * pItem,const TQPoint &pnt,int uColumn)
{
emit doubleClicked((KviTalListViewItem *)pItem,pnt,uColumn);
}
void KviTalListView::redirect_returnPressed(TQListViewItem * pItem)
{
emit returnPressed((KviTalListViewItem *)pItem);
}
void KviTalListView::redirect_spacePressed(TQListViewItem * pItem)
{
emit spacePressed((KviTalListViewItem *)pItem);
}
void KviTalListView::redirect_rightButtonClicked(TQListViewItem * pItem,const TQPoint &pnt,int uColumn)
{
emit rightButtonClicked((KviTalListViewItem *)pItem,pnt,uColumn);
}
void KviTalListView::redirect_rightButtonPressed(TQListViewItem * pItem,const TQPoint &pnt,int uColumn)
{
emit rightButtonPressed((KviTalListViewItem *)pItem,pnt,uColumn);
}
void KviTalListView::redirect_mouseButtonClicked(int iButton,TQListViewItem * pItem,const TQPoint &pnt,int uColumn)
{
emit mouseButtonClicked(iButton,(KviTalListViewItem *)pItem,pnt,uColumn);
}
void KviTalListView::redirect_mouseButtonPressed(int iButton,TQListViewItem * pItem,const TQPoint &pnt,int uColumn)
{
emit mouseButtonPressed(iButton,(KviTalListViewItem *)pItem,pnt,uColumn);
}
void KviTalListView::redirect_contextMenuRequested(TQListViewItem * pItem,const TQPoint &pnt,int uColumn)
{
emit contextMenuRequested((KviTalListViewItem *)pItem,pnt,uColumn);
}
void KviTalListView::redirect_onItem(TQListViewItem * pItem)
{
emit onItem((KviTalListViewItem *)pItem);
}
void KviTalListView::redirect_expanded(TQListViewItem * pItem)
{
emit expanded((KviTalListViewItem *)pItem);
}
void KviTalListView::redirect_collapsed(TQListViewItem * pItem)
{
emit collapsed((KviTalListViewItem *)pItem);
}
struct KviTalCheckListItemPrivate
{
KviTalCheckListItemPrivate():
exclusive( 0 ),
currentState( KviTalCheckListItem::Off ),
statesDict( 0 ),
tristate( FALSE ) {}
KviTalCheckListItem *exclusive;
KviTalCheckListItem::ToggleState currentState;
KviPointerHashTable<void *,KviTalCheckListItem::ToggleState> *statesDict;
bool tristate;
};
// ### obscenity is warranted.
KviTalCheckListItem::KviTalCheckListItem( KviTalCheckListItem *parent, const TQString &text,
Type tt )
: KviTalListViewItem( parent, text, TQString() )
{
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 TQString &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 TQString &text,
Type tt )
: KviTalListViewItem( parent, text, TQString() )
{
myType = tt;
if ( myType == RadioButton ) {
qWarning( "KviTalCheckListItem::KviTalCheckListItem(), radio button must be "
"child of a KviTalCheckListItem" );
}
init();
}
KviTalCheckListItem::KviTalCheckListItem( KviTalListViewItem *parent, KviTalListViewItem *after,
const TQString &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 TQString &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 TQString &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 TQString &text,
const TQPixmap & p )
: KviTalListViewItem( parent, text )
{
myType = RadioButtonController;
setPixmap( 0, p );
init();
}
KviTalCheckListItem::KviTalCheckListItem( KviTalListViewItem *parent, const TQString &text,
const TQPixmap & 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<void *,ToggleState>(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 tqchildren 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 tqchildren 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() );
}
tqrepaint();
}
void KviTalCheckListItem::setCurrentState( ToggleState s )
{
ToggleState old = d->currentState;
d->currentState = s;
if (d->currentState == On)
on = TRUE;
else
on = FALSE;
#if defined(TQT_ACCESSIBILITY_SUPPORT)
if ( old != d->currentState && listView() )
TQAccessible::updateAccessibility( listView()->viewport(), indexOfItem( this ), TQAccessible::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;
TQPoint pos;
int boxsize = lv->tqstyle().pixelMetric(TQStyle::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;
TQRect 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() );
tqrepaint();
break;
case CheckBoxController: {
KviTalListViewItem *item = firstChild();
int childCount = 0;
while ( item ) {
// recursively calling restoreState for tqchildren 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 tqchildren 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 );
}
tqrepaint();
}
}
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 tqchildren.
setStoredState( internalState() , key );
}
void KviTalCheckListItem::setup()
{
KviTalListViewItem::setup();
int h = height();
KviTalListView *lv = listView();
if ( lv )
h = TQMAX( lv->tqstyle().pixelMetric(TQStyle::PM_CheckListButtonSize, lv),
h );
h = TQMAX( h, TQApplication::globalStrut().height() );
setHeight( h );
}
int KviTalCheckListItem::width( const TQFontMetrics& 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->tqstyle().pixelMetric(TQStyle::PM_CheckListButtonSize, lv) + 4;
}
}
return TQMAX( r, TQApplication::globalStrut().width() );
}
void KviTalCheckListItem::paintCell( TQPainter * p, const TQColorGroup & cg,
int column, int width, int align )
{
if ( !p )
return;
KviTalListView *lv = listView();
if ( !lv )
return;
const BackgroundMode bgmode = lv->viewport()->backgroundMode();
const TQColorGroup::ColorRole crole = TQPalette::backgroundRoleFromMode( bgmode );
if ( cg.brush( crole ) != lv->colorGroup().brush( crole ) )
p->fillRect( 0, 0, width, height(), cg.brush( crole ) );
else
lv->paintEmptyArea( p, TQRect( 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;
TQFontMetrics fm( lv->fontMetrics() );
int boxsize = lv->tqstyle().pixelMetric( myType == RadioButtonController ? TQStyle::PM_CheckListControllerSize :
TQStyle::PM_CheckListButtonSize, lv);
int marg = lv->itemMargin();
int r = marg;
// Draw controller / checkbox / radiobutton ---------------------
int styleflags = TQStyle::Style_Default;
if ( internalState() == On ) {
styleflags |= TQStyle::Style_On;
} else if ( internalState() == NoChange ) {
if ( myType == CheckBoxController && !isTristate() )
styleflags |= TQStyle::Style_Off;
else
styleflags |= TQStyle::Style_NoChange;
} else {
styleflags |= TQStyle::Style_Off;
}
if ( isSelected() )
styleflags |= TQStyle::Style_Selected;
if ( isEnabled() && lv->isEnabled() )
styleflags |= TQStyle::Style_Enabled;
if ( myType == RadioButtonController ) {
int x = 0;
if(!parentControl)
x += 3;
if ( !pixmap( 0 ) ) {
lv->tqstyle().tqdrawPrimitive(TQStyle::PE_CheckListController, p,
TQRect(x, 0, boxsize,
fm.height() + 2 + marg),
cg, styleflags, TQStyleOption(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->tqstyle().tqdrawPrimitive(TQStyle::PE_CheckListIndicator, p,
TQRect(x, y, boxsize,
fm.height() + 2 + marg),
cg, styleflags, TQStyleOption(this));
} else { //radio button look
lv->tqstyle().tqdrawPrimitive(TQStyle::PE_CheckListExclusiveIndicator,
p, TQRect(x, y, boxsize,
fm.height() + 2 + marg),
cg, styleflags, TQStyleOption(this));
}
r += boxsize + 4;
}
// Draw text ----------------------------------------------------
p->translate( r, 0 );
p->setPen( TQPen( cg.text() ) );
KviTalListViewItem::paintCell( p, cg, column, width - r, align );
}
void KviTalCheckListItem::paintFocus( TQPainter *p, const TQColorGroup & cg,const TQRect & 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( TQRect( 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) ) ) {
TQRect rect;
int boxsize = lv->tqstyle().pixelMetric(TQStyle::PM_CheckListButtonSize, lv);
if ( lv->columnAlignment(0) == AlignCenter ) {
TQFontMetrics 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