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.
adept/adept/libadept/extendablelist.cpp

333 lines
9.9 KiB

#include <kdebug.h>
#include <tqtimer.h>
#include <tqobjectlist.h>
#include <tqpainter.h>
#include <tqimage.h>
#include <kiconeffect.h>
#include <kiconloader.h>
#include <adept/extendablelist.h>
#include <adept/utils.h>
using namespace adept;
ExtendableList::ExtendableList( TQWidget *p, const char *n )
: KListView( p, n ),
m_toggleColumn( 0 ), m_inDtor( false ),
m_extenderUpdateScheduled( false ),
m_needSort( false ),
m_extenderHighlight( false )
{
// kdDebug() << "connecting processClick har har" << endl;
connect( this, TQT_SIGNAL( clicked( TQListViewItem *,
const TQPoint &, int ) ),
this, TQT_SLOT( processClick( TQListViewItem *,
const TQPoint &, int ) ) );
connect( this, TQT_SIGNAL( moved() ),
this, TQT_SLOT( delayedUpdateExtenders() ) );
connect( this, TQT_SIGNAL( collapsed( TQListViewItem * ) ),
this, TQT_SLOT( delayedUpdateExtenders() ) );
connect( this, TQT_SIGNAL( expanded( TQListViewItem * ) ),
this, TQT_SLOT( delayedUpdateExtenders() ) );
setTreeStepSize( 15 );
m_baseIcon = SmallIcon( u8( "extender_closed" ) );
m_extendedIcon = SmallIcon( u8( "extender_opened" ) );
TQImage img;
img = m_baseIcon;
KIconEffect::toGray( img, 1.0 );
m_unextendableIcon = TQPixmap( img );
}
void ExtendableList::keyPressEvent( TQKeyEvent *e ) {
ExtendableItem *item = dynamic_cast< ExtendableItem* >( currentItem() );
if ( item && item->extendable() ) {
if ( item->extender() && e->key() == TQt::Key_Left ) {
return item->hideExtender();
} else if ( !item->extender() && e->key() == TQt::Key_Right ) {
return item->showExtender();
}
}
return KListView::keyPressEvent( e );
}
void ExtendableList::openToplevel() {
TQListViewItem *i;
for ( i = firstChild(); i != 0; i = i->nextSibling() ) {
i->setOpen( true );
}
}
int ExtendableList::extenderOffset( ExtendableItem *i )
{
int c = 0, x = 0;
while( c < m_toggleColumn ) {
x += columnWidth( c );
c ++;
}
if ( m_toggleColumn >= 0 ) {
// *sigh*
if ( i->pixmap( m_toggleColumn ) )
x += i->pixmap( m_toggleColumn )->width();
if ( rootIsDecorated() )
x += treeStepSize();
if ( i->parent() )
x += treeStepSize();
}
return x;
}
void ExtendableList::updateExtender( ExtendableItem *i )
{
// setUpdatesEnabled( false );
// since updateGeometries is private, we use this dirty trick to
// get at it (since setContentsPos in TQListView calls it
setContentsPos( contentsX(), contentsY() );
if ( !i->isVisible() || ( i->parent() && !i->parent()->isOpen() ) ) {
kdDebug() << "hiding invisible item's extender" << endl;
i->hideExtender();
return;
}
// TQRect rect = tqitemRect( i );
addChild( i->extender(), extenderOffset( i ), itemPos( i ) );
// addChild( i->extender(), x, rect.y() );
i->extender()->show();
i->extender()->resize( visibleWidth() - extenderOffset( i ),
i->extender()->height() );
if ( i->height() != i->extender()->frameSize().height() ) {
i->setHeight( i->extender()->frameSize().height() );
delayedUpdateExtenders(); // re-update since we broke tqlayout
}
i->extender()->setupColors();
// setUpdatesEnabled( true );
// addChild( i->extender(), x, itemPos( i ) );
// TQTimer::singleShot( 0, this, TQT_SLOT( triggerUpdate() ) );
// TQTimer::singleShot( 0, i->extender(), TQT_SLOT( setupColors() ) );
}
void ExtendableList::delayedUpdateExtenders()
{
if ( m_extenderUpdateScheduled )
return;
m_extenderUpdateScheduled = true;
// kdDebug() << "ExtendableList::delayedUpdateExtenders()" << endl;
TQTimer::singleShot( 0, this, TQT_SLOT( updateExtenders() ) );
}
void ExtendableList::clear()
{
kdDebug() << "ExtendableList::clear()" << endl;
KListView::clear();
kdDebug() << "end of ExtendableList::clear()" << endl;
}
void ExtendableList::show()
{
KListView::show();
updateExtenders();
}
void ExtendableList::showEvent( TQShowEvent *e )
{
KListView::showEvent( e );
updateExtenders();
}
void ExtendableList::resizeEvent( TQResizeEvent *e )
{
KListView::resizeEvent( e );
updateExtenders();
// delayedUpdateExtenders();
}
void ExtendableList::updateExtenders()
{
m_extenderUpdateScheduled = false;
setUpdatesEnabled( false );
// updateGeometries();
// since updateGeometries is private, we use this dirty trick to
// get at it (since setContentsPos in TQListView calls it
setContentsPos( contentsX(), contentsY() );
extendersChanged();
kdDebug() << "ExtendableList::updateExtenders(); count = "
<< m_extenders.size() << endl;
if ( m_needSort ) {
std::sort( m_extenders.begin(), m_extenders.end(), ExtendableItem::s_less );
m_needSort = false;
}
std::for_each( m_extenders.begin(), m_extenders.end(),
std::bind1st( std::mem_fun( &ExtendableList::updateExtender ),
this ) );
setUpdatesEnabled( true );
// triggerUpdate();
if ( !m_extenderUpdateScheduled )
TQTimer::singleShot( 0, this, TQT_SLOT( triggerUpdate() ) );
/* if ( m_extenders.empty() )
TQTimer::singleShot( 0, this, TQT_SLOT( triggerUpdate() ) ); */
// TQTimer::singleShot( 0, this, TQT_SIGNAL( extendersChanged() ) );
}
void ExtendableList::addExtender( ExtendableItem *item )
{
m_extenders.push_back( item );
m_needSort = true;
// std::sort( m_extenders.begin(), m_extenders.end(), ExtendableItem::s_less );
// updateExtender( item );
delayedUpdateExtenders();
}
void ExtendableList::removeExtender( ExtendableItem *i )
{
kdDebug() << "ExtendableList::removeExtender( " << i << " )" << endl;
m_extenders.erase( std::remove( m_extenders.begin(),
m_extenders.end(), i ),
m_extenders.end() );
// the above retains ordering so no need to re-sort
if (!m_inDtor)
delayedUpdateExtenders();
}
void ExtendableList::processClick( TQListViewItem *it,
const TQPoint &pt, int c )
{
// if (! it) return;
ExtendableItem *item = dynamic_cast< ExtendableItem* >( it );
if (!item) return;
kdDebug() << "ExtendableList::processClick (a real item)" << endl;
if (c == m_toggleColumn)
item->toggleExtender();
if ( item->extender() )
item->extender()->setupColors();
delayedUpdateExtenders();
/* if (item->extender()) {
if (c == m_toggleColumn)
item->toggleExtender();
} else
item->toggleExtender(); */
}
ExtendableList::~ExtendableList() {
}
ExtendableList *ExtendableItem::list()
{
return dynamic_cast< ExtendableList * >( listView() );
}
bool ExtendableItem::s_less(
const ExtendableItem *a, const ExtendableItem *b )
{
return a->less( b );
}
int ExtendableItem::compare( TQListViewItem *i, int c, bool asc ) const
{
ExtendableItem *o = dynamic_cast< ExtendableItem * >( i );
return int( o->less( this ) ) - int( less( o ) );
}
void ExtendableItem::updateIcon() {
TQPixmap p;
if ( !extender() ) {
p = list()->baseIcon();
if ( !extendable() && !firstChild() ) {
p = list()->unextendableIcon();
}
} else {
p = list()->extendedIcon();
}
setPixmap( list()->toggleColumn(), p );
// umm hack
if ( dynamic_cast< ExtendableItem * >( parent() ) )
dynamic_cast< ExtendableItem * >( parent() )->updateIcon();
}
void ExtendableItem::toggleExtender()
{
if (m_extender) {
setup();
if( list() ) // this could as well be 0... bah
list()->removeExtender( this );
delete m_extender;
m_extender = 0;
} else {
m_extender = createExtender();
if (m_extender) {
m_extender->setItem( this );
list()->addExtender( this );
}
if ( !m_extender && firstChild() ) {
setOpen( !isOpen() );
}
}
updateIcon();
}
void ExtendableItem::paintBranches( TQPainter *p,
const TQColorGroup &cg, int w, int y, int h )
{
/* if (!isAlternate())
p->setBackgroundColor(
KGlobalSettings::alternateBackgroundColor() );
p->eraseRect( 0, y, w, h ); */
p->eraseRect( 0, 0, w, h );
}
/* void ExtendableItem::paintCell( TQPainter *p, const TQColorGroup &cg,
int column, int width, int tqalignment )
{
TQPixmap pm( width, height() );
TQPainter _p( &pm );
KListViewItem::paintCell( &_p, cg, column, width, tqalignment );
p->drawPixmap( 0, 0, pm );
} */
static void setcolor( TQWidget *w, ExtendableItem *i ) {
if ( i->isSelected() && i->list()->extenderHighlight() )
w->setPaletteBackgroundColor( w->tqcolorGroup().highlight() );
else if ( i->isAlternate() )
w->setPaletteBackgroundColor(
KGlobalSettings::alternateBackgroundColor() );
else
w->setPaletteBackgroundColor( w->tqcolorGroup().base() );
// w->setBackgroundMode( TQWidget::PaletteBase );
}
void ItemExtender::setupColors()
{
if ( !item() ) return;
setcolor( this, item() );
TQObjectList *chld = queryList( TQWIDGET_OBJECT_NAME_STRING );
TQObjectListIt it( *chld );
TQWidget *o;
while ((o = dynamic_cast< TQWidget * >( it.current() )) != 0) {
setcolor( o, item() );
++it;
}
}
ExtendableItem::~ExtendableItem()
{
// kdDebug() << "~ExtendableList; list = " << list() << endl;
// kdDebug() << "extender() = " << extender() << endl;
while ( firstChild() )
delete firstChild(); // har har
if( extender() && list() ) // list() could be 0...
list()->removeExtender( this );
if (extender())
extender()->deleteLater();
}