|
|
|
#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 )
|
|
|
|
: TDEListView( 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;
|
|
|
|
TDEIconEffect::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 TDEListView::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;
|
|
|
|
TDEListView::clear();
|
|
|
|
kdDebug() << "end of ExtendableList::clear()" << endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ExtendableList::show()
|
|
|
|
{
|
|
|
|
TDEListView::show();
|
|
|
|
updateExtenders();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ExtendableList::showEvent( TQShowEvent *e )
|
|
|
|
{
|
|
|
|
TDEListView::showEvent( e );
|
|
|
|
updateExtenders();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ExtendableList::resizeEvent( TQResizeEvent *e )
|
|
|
|
{
|
|
|
|
TDEListView::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 );
|
|
|
|
TDEListViewItem::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();
|
|
|
|
}
|