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.
769 lines
24 KiB
769 lines
24 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"
|
|
|
|
|
|
#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 )
|
|
tqWarning( "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 )
|
|
tqWarning( "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 ) {
|
|
tqWarning( "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 ) {
|
|
tqWarning( "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 )
|
|
tqWarning( "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 )
|
|
tqWarning( "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 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 ) ) {
|
|
tqWarning( "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(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->style().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() );
|
|
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 = TQMAX( lv->style().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->style().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->style().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->style().drawPrimitive(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->style().drawPrimitive(TQStyle::PE_CheckListIndicator, p,
|
|
TQRect(x, y, boxsize,
|
|
fm.height() + 2 + marg),
|
|
cg, styleflags, TQStyleOption(this));
|
|
} else { //radio button look
|
|
lv->style().drawPrimitive(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->style().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"
|
|
|
|
|
|
|