#include #include #include #include #include #include #include #include #include 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 = itemRect( 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 layout } 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( TDEGlobalSettings::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 alignment ) { TQPixmap pm( width, height() ); TQPainter _p( &pm ); KListViewItem::paintCell( &_p, cg, column, width, alignment ); p->drawPixmap( 0, 0, pm ); } */ static void setcolor( TQWidget *w, ExtendableItem *i ) { if ( i->isSelected() && i->list()->extenderHighlight() ) w->setPaletteBackgroundColor( w->colorGroup().highlight() ); else if ( i->isAlternate() ) w->setPaletteBackgroundColor( TDEGlobalSettings::alternateBackgroundColor() ); else w->setPaletteBackgroundColor( w->colorGroup().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(); }