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.
708 lines
21 KiB
708 lines
21 KiB
// -*- Mode: C++; c-basic-offset: 4; -*-
|
|
#include <tqlabel.h>
|
|
#include <tqtimer.h>
|
|
#include <tqpainter.h>
|
|
#include <tqpushbutton.h>
|
|
#include <tqthread.h>
|
|
#include <tqtextbrowser.h>
|
|
|
|
#include <kpopupmenu.h>
|
|
#include <kdebug.h>
|
|
#include <klineedit.h>
|
|
#include <klocale.h>
|
|
#include <kapplication.h>
|
|
#include <kglobal.h>
|
|
#include <kiconloader.h>
|
|
|
|
#include <functional>
|
|
#include <iostream>
|
|
|
|
#include <apt-front/cache/cache.h>
|
|
#include <apt-front/actor.h>
|
|
#include <apt-front/cache/component/packages.h>
|
|
#include <apt-front/cache/component/state.h>
|
|
#include <apt-front/predicate/factory.h>
|
|
|
|
#include <adept/utils.h>
|
|
#include <adept/lister.h>
|
|
#include <adept/packageinfo.h>
|
|
|
|
using namespace aptFront;
|
|
using namespace aptFront::predicate;
|
|
using namespace aptFront::cache;
|
|
using namespace aptFront::utils;
|
|
using namespace adept;
|
|
|
|
Lister::Lister( TQWidget *tqparent, const char *name )
|
|
: ExtendableList( tqparent, name ),
|
|
m_rangeProvider( 0 ),
|
|
m_baseF( predicate::True< entity::Entity >() ),
|
|
m_interactiveF( True<entity::Entity>() ), m_itemCount( -1 ),
|
|
m_rebuildScheduled( false ), m_inRebuild( false ), m_cancelRebuild( false ),
|
|
m_openToplevel( false ), m_rebuildMutex( true )
|
|
{
|
|
observeComponent< component::State >();
|
|
observeComponent< component::Packages >();
|
|
observeComponent< component::PackageTags >();
|
|
setRootIsDecorated( false );
|
|
setSelectionModeExt( Extended );
|
|
setAllColumnsShowFocus (true);
|
|
|
|
m_icons[ u8( "package-install" ) ] = u8( "adept_install" );
|
|
m_icons[ u8( "package-remove" ) ] = u8( "adept_remove" );
|
|
m_icons[ u8( "package-upgrade" ) ] = u8( "adept_upgrade" );
|
|
m_icons[ u8( "package-keep" )] = u8( "adept_keep" );
|
|
m_icons[ u8( "package-reinstall" )] = u8( "adept_reinstall" );
|
|
m_icons[ u8( "package-purge" )] = u8( "adept_purge" );
|
|
|
|
setSorting( -1 );
|
|
// addColumn(" ", 40);
|
|
// addColumn(" ", 18);
|
|
addColumn( i18n( "Package" ), 180);
|
|
addColumn( i18n( "tqStatus" ), 110);
|
|
addColumn( i18n( "Requested" ), 90);
|
|
addColumn( i18n( "Description" ), 300);
|
|
setToggleColumn( 0 );
|
|
|
|
setResizeMode (LastColumn);
|
|
connect( this, TQT_SIGNAL( selectionChanged() ), TQT_SLOT( updateActions() ) );
|
|
connect( this,
|
|
TQT_SIGNAL( contextMenuRequested( TQListViewItem *,
|
|
const TQPoint &, int ) ),
|
|
this, TQT_SLOT(
|
|
contextMenu( TQListViewItem *, const TQPoint &, int) ) );
|
|
m_tip = 0;
|
|
// m_tip = new ListerTooltip( viewport(), this );
|
|
}
|
|
|
|
Lister::~Lister()
|
|
{
|
|
delete m_tip;
|
|
}
|
|
|
|
void Lister::scheduleRebuild()
|
|
{
|
|
if (!m_rebuildScheduled) {
|
|
// kdDebug() << "Lister scheduling rebuild" << endl;
|
|
TQTimer::singleShot( 0, this, TQT_SLOT( rebuild() ) );
|
|
}
|
|
m_rebuildScheduled = true;
|
|
}
|
|
|
|
void Lister::updateActions()
|
|
{
|
|
emit actionsChanged( this );
|
|
}
|
|
|
|
void Lister::notifyPostChange( component::Base * )
|
|
{
|
|
kdDebug() << "notifyRefresh()" << endl;
|
|
updateActions();
|
|
triggerUpdate();
|
|
}
|
|
|
|
void Lister::notifyPreRebuild( component::Base *b )
|
|
{
|
|
kdDebug() << "Lister::notifyPreRebuild( " << b << " )" << endl;
|
|
Cache &c = cache::Global::get( m_cache );
|
|
setEnabled( false );
|
|
if ( dynamic_cast< component::PackageTags * >( b ) != 0 ) {
|
|
kdDebug() << "clearing cardinality" << endl;
|
|
m_cardinality.clear();
|
|
}
|
|
if ( dynamic_cast< component::Packages * >( b ) != 0 ) {
|
|
kdDebug() << "clearing lister" << endl;
|
|
clear();
|
|
m_items.clear();
|
|
m_cardinality.clear();
|
|
}
|
|
}
|
|
|
|
void Lister::notifyPostRebuild( component::Base *b )
|
|
{
|
|
kdDebug() << "Lister::notifyPostRebuild( " << b << " )" << endl;
|
|
scheduleRebuild();
|
|
if ( dynamic_cast< component::State * >( b ) != 0 ) {
|
|
setEnabled( true );
|
|
}
|
|
}
|
|
|
|
bool lessByName( const entity::Entity &e1, const entity::Entity &e2 )
|
|
{
|
|
if ( e1.is< entity::Named >() && e2.is< entity::Named >() ) {
|
|
entity::Named &n1 = downcast< entity::Named >( e1 ),
|
|
&n2 = downcast< entity::Named >( e2 );
|
|
return n1.name() < n2.name();
|
|
}
|
|
return e1 < e2;
|
|
}
|
|
|
|
bool Lister::cancelRebuild() {
|
|
// kdDebug() << "cancel rebuild: " << m_inRebuild << ", " << m_cancelRebuild << endl;
|
|
if ( m_inRebuild ) {
|
|
m_rebuildScheduled = false;
|
|
m_cancelRebuild = true;
|
|
}
|
|
if ( !cache::Global::get( m_cache ).isOpen() ) {
|
|
m_rebuildScheduled = false;
|
|
return true;
|
|
}
|
|
return m_cancelRebuild;
|
|
}
|
|
|
|
void Lister::cleanRebuild()
|
|
{
|
|
scheduleRebuild();
|
|
}
|
|
|
|
Lister::CreateItem::CreateItem( Lister *_l, ListerItem *p )
|
|
: l( _l ), time( 0 ), items( 0 ), last( 0 ), tqparent( p )
|
|
{
|
|
}
|
|
|
|
Lister::CreateItem::~CreateItem()
|
|
{
|
|
// delete timer;
|
|
}
|
|
|
|
Lister::Map::value_type Lister::CreateItem::operator()( entity::Entity e )
|
|
{
|
|
items ++;
|
|
if ( l->m_cancelRebuild ) throw 0; // XXX proper exception please
|
|
// kdDebug() << "trying to acquire mutex" << endl;
|
|
l->m_rebuildMutex.lock();
|
|
// kdDebug() << "mutex acquired" << endl;
|
|
|
|
// count tags
|
|
if ( e.is< entity::Package >() ) {
|
|
const entity::Tag::Set &tags = downcast< entity::Package >( e ).tags();
|
|
for (entity::Tag::Set::iterator i = tags.begin(); i != tags.end(); ++ i )
|
|
l->m_cardinality[ *i ] ++;
|
|
}
|
|
|
|
if ( last ) {
|
|
if ( tqparent )
|
|
last = new ListerItem( tqparent, last, e );
|
|
else
|
|
last = new ListerItem( l, last, e );
|
|
} else {
|
|
if ( tqparent )
|
|
last = new ListerItem( tqparent, e );
|
|
else
|
|
last = new ListerItem( l, e );
|
|
}
|
|
l->m_rebuildMutex.unlock();
|
|
if ( e.is< entity::Relation >() )
|
|
// this should be safe because the tqparent thread is waiting
|
|
// for us and ensures that universe (libapt-front) is kept
|
|
// unchanged while we run
|
|
l->insertRangeInternal( InsertRangePair(
|
|
last, downcast< entity::Relation >( e ).targetPackages() ) );
|
|
// we may want to use recursive async call instead? why?
|
|
/* Threads::enqueue(
|
|
asyncCall( std::bind2nd( std::mem_fun( &Lister::insertRangeInternal ),
|
|
InsertRangePair(
|
|
last,
|
|
downcast< entity::Relation >( e ).targetPackages() ) ),
|
|
l ), &(l->m_rebuildMutex) );
|
|
*/
|
|
return std::make_pair( e, last );
|
|
}
|
|
|
|
void Lister::reallyUpdate()
|
|
{
|
|
bool en = isUpdatesEnabled();
|
|
setUpdatesEnabled( true );
|
|
triggerUpdate();
|
|
setUpdatesEnabled( en );
|
|
}
|
|
|
|
void Lister::insertRange( Range r ) {
|
|
insertRangeInternal( InsertRangePair( 0, r ) );
|
|
}
|
|
void Lister::insertRangeInternal( InsertRangePair a )
|
|
{
|
|
// kdDebug() << "insertRange running..." << endl;
|
|
try {
|
|
std::transform( a.second, a.second.end(),
|
|
inserter( m_items, m_items.begin() ),
|
|
CreateItem( this, a.first ) );
|
|
} catch ( ... ) {}
|
|
m_itemCount = m_items.size();
|
|
}
|
|
|
|
/* void Lister::rebuildInsertRange( Range r ) {
|
|
insertRange( 0, r );
|
|
} */
|
|
|
|
void Lister::rebuild()
|
|
{
|
|
Cache &c = cache::Global::get( m_cache );
|
|
if ( cancelRebuild() ) {
|
|
scheduleRebuild();
|
|
return;
|
|
}
|
|
|
|
m_inRebuild = true;
|
|
m_rebuildMutex.lock();
|
|
|
|
emit rebuildStarted();
|
|
|
|
c.progress().OverallProgress( 0, 0, 0, i18n( "Filtering" ) );
|
|
kdDebug() << "rebuild running" << endl;
|
|
clock_t _c = clock(), C;
|
|
for ( Cardinality::iterator i = m_cardinality.begin();
|
|
i != m_cardinality.end(); ++i )
|
|
i->second = 0;
|
|
|
|
kdDebug() << "querying m_rangeProvider " << m_rangeProvider << "..." << endl;
|
|
|
|
Range r = filteredRange( m_rangeProvider ?
|
|
m_rangeProvider->listerRange() : range( VectorRange() ),
|
|
m_baseF );
|
|
C = (clock() - _c) / 1000; _c = clock();
|
|
|
|
setUpdatesEnabled( false );
|
|
kdDebug() << "clearing..." << endl;
|
|
clear();
|
|
m_items.clear();
|
|
|
|
kdDebug() << "asyncCall to rebuildInsertRange..." << endl;
|
|
TQThread *t = asyncCall( std::bind2nd(
|
|
std::mem_fun( &Lister::insertRangeInternal ),
|
|
InsertRangePair( 0, r ) ),
|
|
this );
|
|
|
|
kdDebug() << "starting the thread..." << endl;
|
|
|
|
TQTimer timer;
|
|
connect( &timer, TQT_SIGNAL( timeout() ),
|
|
this, TQT_SLOT( reallyUpdate() ) );
|
|
timer.start( 0 );
|
|
|
|
m_rebuildMutex.unlock();
|
|
Threads::enqueue( t, &m_rebuildMutex );
|
|
Threads::wait();
|
|
|
|
timer.stop();
|
|
|
|
kdDebug() << "thread finished..." << endl;
|
|
C = (clock() - _c) / 1000; _c = clock();
|
|
kdDebug() << m_items.size() << " entities synced, time = " << C << endl;
|
|
|
|
setUpdatesEnabled( true );
|
|
c.progress().Done();
|
|
if ( m_openToplevel ) openToplevel();
|
|
triggerUpdate();
|
|
|
|
if ( !m_cancelRebuild ) {
|
|
for ( Cardinality::iterator i = m_cardinality.begin();
|
|
i != m_cardinality.end(); ++i )
|
|
if ( i->second == m_itemCount )
|
|
i->second = -1;
|
|
emit cardinalityChanged( m_cardinality );
|
|
}
|
|
|
|
m_inRebuild = false;
|
|
m_rebuildScheduled = false;
|
|
m_cancelRebuild = false;
|
|
emit rebuildFinished();
|
|
}
|
|
|
|
void Lister::baseAnd( Predicate o )
|
|
{
|
|
m_baseF = predicate::predicate( m_baseF and o );
|
|
// emit filterChanged( m_baseF );
|
|
cancelRebuild();
|
|
scheduleRebuild();
|
|
}
|
|
|
|
void Lister::baseSet( Predicate o )
|
|
{
|
|
m_baseF = o;
|
|
// emit filterChanged( m_baseF );
|
|
cancelRebuild();
|
|
scheduleRebuild();
|
|
}
|
|
|
|
void Lister::interactiveAnd( Predicate o )
|
|
{
|
|
m_interactiveF = predicate::predicate( m_interactiveF and o );
|
|
cancelRebuild();
|
|
scheduleRebuild();
|
|
}
|
|
|
|
void Lister::interactiveDrop( Predicate o )
|
|
{
|
|
m_interactiveF = predicate::remove( m_interactiveF, o );
|
|
cancelRebuild();
|
|
scheduleRebuild();
|
|
}
|
|
|
|
bool Lister::itemSelected( Map::value_type i )
|
|
{
|
|
return not i.second->isSelected();
|
|
}
|
|
|
|
entity::Entity Lister::extractKey( Map::value_type i )
|
|
{
|
|
return i.first;
|
|
}
|
|
|
|
Lister::VectorRange Lister::selection()
|
|
{
|
|
VectorRange ret;
|
|
Map m;
|
|
std::remove_copy_if( m_items.begin(), m_items.end(),
|
|
inserter( m, m.begin() ),
|
|
itemSelected );
|
|
std::transform( m.begin(), m.end(),
|
|
consumer( ret ),
|
|
extractKey );
|
|
return ret;
|
|
}
|
|
|
|
Lister::VectorRange Lister::content()
|
|
{
|
|
VectorRange ret;
|
|
std::transform( m_items.begin(), m_items.end(),
|
|
consumer( ret ),
|
|
extractKey );
|
|
return ret;
|
|
}
|
|
|
|
TQString ListerItem::text( int column ) const
|
|
{
|
|
// if (column == 0) return ""; // until we redo paintcell for the col
|
|
if (entity().is<entity::Package>()) {
|
|
entity::Package p = entity();
|
|
switch (column) {
|
|
case 0: return u8( p.name( u8( i18n( "n/a" ) ) ) );
|
|
case 1: return u8( p.statusString( u8( i18n( "n/a" ) ) ) );
|
|
case 2: return u8( p.actionString( u8( i18n( "n/a" ) ) ) );
|
|
case 3: return u8( p.shortDescription( u8( i18n( "n/a" ) ) ) );
|
|
// case 2: return p.candidateVersion().versionString();
|
|
}
|
|
}
|
|
if ( entity().is< entity::Relation >() && column == 0 )
|
|
return downcast< entity::Relation >( entity() ).format();
|
|
return u8( "" );
|
|
}
|
|
|
|
void ListerItem::paintCell (TQPainter *p, const TQColorGroup &cg,
|
|
int column, int width, int tqalignment )
|
|
{
|
|
if ( width <= 0 )
|
|
return;
|
|
TQColorGroup _cg( cg );
|
|
TQColor c = _cg.text();
|
|
TQPixmap pm( width, height() );
|
|
TQPainter _p( &pm );
|
|
if (entity().is<entity::Package>()) {
|
|
entity::Package p = entity();
|
|
if (column == 1)
|
|
c = statusColor( p );
|
|
if (column == 2)
|
|
c = actionColor( p );
|
|
}
|
|
_cg.setColor( TQColorGroup::Text, c );
|
|
KListViewItem::paintCell( &_p, _cg, column, width, AlignTop );
|
|
p->drawPixmap( 0, 0, pm );
|
|
}
|
|
|
|
void Lister::contextMenu( TQListViewItem *it, const TQPoint &pt, int /*c*/ )
|
|
{
|
|
if (! it) // check for actor when we have one...
|
|
return;
|
|
m_context = dynamic_cast< ListerItem * >( it );
|
|
VectorRange sel = selection();
|
|
// entity::Package p = (dynamic_cast<ListerItem *>(it)->entity());
|
|
KPopupMenu *m = new KPopupMenu (this);
|
|
utils::Range< Actor > r = actor::Global< entity::Package >::list();
|
|
int id = 8;
|
|
try {
|
|
for (; r != r.end(); ++r) {
|
|
m->insertItem( SmallIconSet( m_icons[ u8( r->name() ) ] ),
|
|
r->prettyName(), id );
|
|
m->setItemEnabled(
|
|
id, r->possible( utils::upcastRange< entity::Package >( sel ) ) );
|
|
++id;
|
|
}
|
|
} catch ( std::bad_cast ) {} // ignore (this is broken, but
|
|
// easiest fix)
|
|
bool open = m_context->extender();
|
|
m->insertItem( open ? i18n( "Hide details" ) :
|
|
i18n( "Show details" ), open ? 1 : 0 );
|
|
connect(m, TQT_SIGNAL(activated(int)), this, TQT_SLOT(contextActivated(int)));
|
|
m->exec(pt);
|
|
delete m;
|
|
}
|
|
|
|
void Lister::contextActivated( int id )
|
|
{
|
|
VectorRange sel = selection();
|
|
try {
|
|
if (id >= 8) {
|
|
utils::Range< Actor > r = actor::Global< entity::Package >::list();
|
|
std::advance( r, id - 8 );
|
|
(*r)( utils::upcastRange< entity::Package >( sel ) );
|
|
updateActions();
|
|
}
|
|
if (id < 8) {
|
|
VectorRange i = sel.begin();
|
|
while (i != i.end()) {
|
|
if (id == 0)
|
|
m_items[*i]->showExtender();
|
|
if (id == 1)
|
|
m_items[*i]->hideExtender();
|
|
++ i;
|
|
}
|
|
}
|
|
} catch ( std::bad_cast ) {} // ignore (this is broken, but
|
|
}
|
|
|
|
ListerItemExtender::~ListerItemExtender()
|
|
{
|
|
}
|
|
|
|
ListerItemExtender::ListerItemExtender( TQWidget *tqparent, const char * n)
|
|
: ListerItemExtenderUi( tqparent, n )
|
|
{
|
|
observeComponent< component::State >();
|
|
adjustFontSize( m_description, -1 );
|
|
connect( m_details, TQT_SIGNAL( clicked() ),
|
|
this, TQT_SLOT( detailsClicked() ) );
|
|
|
|
m_packageInfo->adjustFontSize( -1 );
|
|
m_packageInfo->hidetqStatus();
|
|
}
|
|
|
|
void ListerItemExtender::detailsClicked() {
|
|
detailsRequested( m_entity );
|
|
}
|
|
|
|
ListerItem *ListerItemExtender::item()
|
|
{
|
|
return dynamic_cast< ListerItem * >( m_item );
|
|
}
|
|
|
|
void ListerItemExtender::mouseReleaseEvent( TQMouseEvent *e ) {
|
|
e->ignore();
|
|
if ( tqchildAt( e->pos() ) != static_cast< TQWidget * >( m_name ) )
|
|
e->accept();
|
|
}
|
|
void ListerItemExtender::setItem( ExtendableItem *i )
|
|
{
|
|
ItemExtender::setItem( i );
|
|
m_entity = item()->entity();
|
|
// setupColors();
|
|
|
|
kdDebug() << "ListerItemExtender::setItem connecting" << endl;
|
|
connect( this, TQT_SIGNAL( detailsRequested( Lister::Entity ) ),
|
|
item()->list(), TQT_SIGNAL( detailsRequested( Lister::Entity ) ) );
|
|
|
|
entity::Version v;
|
|
entity::Package p;
|
|
|
|
if ( m_entity.is< entity::Version >() ) {
|
|
v = m_entity;
|
|
p = v.package();
|
|
}
|
|
|
|
if ( m_entity.is< entity::Package >() ) {
|
|
p = m_entity;
|
|
v = p.anyVersion();
|
|
}
|
|
|
|
if ( !v.valid() ) {
|
|
m_logical->setText( i18n( "Immutable" ) );
|
|
m_logical->setEnabled( false );
|
|
m_details->setEnabled( false );
|
|
return;
|
|
}
|
|
|
|
m_name->setText( /* TQString( "<b>" ) + */
|
|
v.package().name( std::string( "oops" ) ) /* + "</b>" */ );
|
|
TQString l = u8( v.longDescription(
|
|
u8( i18n( "No long description available" ) ) ) );
|
|
|
|
m_description->setText( TQString( "<qt>" )
|
|
+ formatLongDescription( l ) + "</qt>" );
|
|
m_description->adjustSize();
|
|
m_description->installEventFilter( this );
|
|
|
|
m_packageInfo->setVersion( v, m_entity.is< entity::Version >() );
|
|
|
|
notifyPostChange( 0 );
|
|
}
|
|
|
|
void ListerItemExtender::notifyPostRebuild( component::Base *b )
|
|
{ // need to catch undo/redo effects
|
|
return notifyPostChange( b );
|
|
}
|
|
|
|
void ListerItemExtender::notifyPostChange( component::Base * )
|
|
{
|
|
// without the timer to break it, there could be a loop where
|
|
// we connect the clicked() signal to a slot which would be
|
|
// invoked right away when we return -> evil
|
|
TQTimer::singleShot( 0, this, TQT_SLOT( updateLogical() ) );
|
|
}
|
|
|
|
void ListerItemExtender::updateLogical() {
|
|
entity::Package pkg = entity();
|
|
EntityActor *a = 0;
|
|
|
|
m_status->setText( colorify(
|
|
statusColor( pkg ),
|
|
u8( pkg.statusString( u8( i18n( "Unknown" ) ) ) ) ) );
|
|
m_change->setText( colorify(
|
|
actionColor( pkg ),
|
|
u8( pkg.actionString( u8( i18n( "Unknown" ) ) ) ) ) );
|
|
|
|
|
|
m_logical->setEnabled( true );
|
|
if (pkg.canUpgrade()) {
|
|
a = new EntityActor( pkg.upgrade() );
|
|
} else if (pkg.canInstall()) {
|
|
a = new EntityActor( pkg.install() );
|
|
} else if (pkg.canKeep()) {
|
|
a = new EntityActor( pkg.keep() );
|
|
} else if (pkg.canRemove()) {
|
|
a = new EntityActor( pkg.remove() );
|
|
}
|
|
|
|
if (a) {
|
|
m_logical->setText( u8( a->actor().prettyName() ) );
|
|
connect( m_logical, TQT_SIGNAL( clicked() ),
|
|
a, TQT_SLOT( destructiveAct() ) );
|
|
} else {
|
|
m_logical->setText( i18n( "Immutable" ) );
|
|
m_logical->setEnabled( false );
|
|
}
|
|
|
|
}
|
|
|
|
bool ListerItemExtender::eventFilter( TQObject *o, TQEvent *e )
|
|
{
|
|
if (o == m_description && e->type() == TQEvent::Wheel) {
|
|
// kdDebug() << "discarding wheel event..." << endl;
|
|
TQApplication::sendEvent( this, e );
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void ListerItemExtender::resize( int w, int h )
|
|
{
|
|
int namew = - item()->lister()->extenderOffset( item() ) - 2
|
|
- tqlayout()->margin()
|
|
- tqlayout()->spacing()
|
|
+ item()->lister()->columnWidth( 0 );
|
|
int statw = item()->lister()->columnWidth( 1 )
|
|
- tqlayout()->spacing();
|
|
int chw = item()->lister()->columnWidth( 2 ) - 2
|
|
- tqlayout()->spacing();
|
|
m_name->setMinimumWidth( namew );
|
|
m_status->setMinimumWidth( statw );
|
|
m_change->setMinimumWidth( chw );
|
|
m_packageInfo->adjustSize();
|
|
m_leftHeight = m_name->height() + m_packageInfo->height()
|
|
+ m_logical->height() + 20;
|
|
TQWidget::resize( w, 500 );
|
|
TQWidget::resize(
|
|
w,
|
|
TQMAX( m_description->contentsHeight() + 16,
|
|
m_leftHeight ) );
|
|
}
|
|
|
|
bool entityLess::operator()( entity::Entity e1, entity::Entity e2 )
|
|
{
|
|
if ( e1.is< entity::Package >() ) {
|
|
if ( e2.is< entity::Package >() )
|
|
return e1 < e2;
|
|
return true;
|
|
}
|
|
|
|
if ( e1.is< entity::Version >() ) {
|
|
if ( e2.is< entity::Package >() )
|
|
return false;
|
|
if ( e2.is< entity::Version >() )
|
|
return e1 < e2;
|
|
return true;
|
|
}
|
|
|
|
if ( e1.is< entity::Relation >() ) {
|
|
if ( e2.is< entity::Package >() )
|
|
return false;
|
|
if ( e2.is< entity::Version >() )
|
|
return false;
|
|
if ( e2.is< entity::Relation >() )
|
|
return e1 < e2;
|
|
return true;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool ListerItem::less( const ExtendableItem *b ) const
|
|
{
|
|
entity::Entity e1 = entity(), e2 = dynamic_cast< const ListerItem * >( b )->entity();
|
|
return entityLess()( e1, e2 );
|
|
}
|
|
|
|
bool ListerItem::keepLess( const ListerItem *o ) const
|
|
{
|
|
const ListerItem *b = o;
|
|
while ( b != 0 ) {
|
|
if ( b == this )
|
|
return false;
|
|
b = b->m_previous;
|
|
}
|
|
while ( o != 0 ) {
|
|
o = dynamic_cast< const ListerItem * >( o->nextSibling() );
|
|
if ( o == this )
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
TQString ListerTooltip::format( const TQString &what,
|
|
const TQString &txt, bool nobr )
|
|
{
|
|
TQString ret = "<b>" + what + "</b> " + (nobr ? "<nobr>" : "")
|
|
+ txt + (nobr ? "</nobr>" : "") + "<br>";
|
|
return ret;
|
|
}
|
|
|
|
void ListerTooltip::maybeTip( const TQPoint &pt )
|
|
{
|
|
if ( !m_parent )
|
|
return;
|
|
kdDebug() << "ListTreeWidgetTooltip::maybeTip ()" << endl;
|
|
ListerItem *x = dynamic_cast<ListerItem *>( m_parent->itemAt( pt ) );
|
|
if ( !x )
|
|
return;
|
|
if ( x->extender() )
|
|
return; // no tips for extended items, thank you
|
|
TQString str = u8( "<qt>" );
|
|
TQString descr, cand, cur;
|
|
descr = cand = cur = i18n( "<i>Not available</i>" );
|
|
entity::Package p( x->entity() );
|
|
descr = p.shortDescription( std::string(
|
|
i18n( "<i>Not available</i>" ).local8Bit() ) );
|
|
try {
|
|
cand = u8( p.candidateVersion().versionString() );
|
|
} catch (...) {}
|
|
try {
|
|
cur = u8( p.installedVersion().versionString() );
|
|
} catch (...) {}
|
|
|
|
str += format( i18n( "Package:" ), u8( p.name() ) );
|
|
str += format( i18n( "Description:" ), descr );
|
|
str += format( i18n( "Current Version:" ), cur );
|
|
str += format( i18n( "Candidate Version:" ), cand );
|
|
|
|
str.append( u8( "</qt>" ) );
|
|
tip( m_parent->tqitemRect( x ), str );
|
|
}
|