#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace adept; ItemChangelog* global_changelog = new ItemChangelog(); PackageDetails::PackageDetails( TQWidget *w, const char *n ) : PackageDetailsUi( w, n ), m_thread( 0 ), m_qtMutex( true ), m_logicalAct( 0 ), m_removeAct( 0 ), m_fileListRunning( false ) { m_toolbar->setIconSize( 22 ); m_toolbar->setIconText( TDEToolBar::IconTextRight ); m_toolbar->insertButton( u8( "back" ), BBack, false, i18n( "Back" ) ); m_toolbar->insertButton( u8( "forward" ), BForward, false, i18n( "Forward" ) ); m_toolbar->insertLineSeparator(); m_toolbar->insertButton( u8( "" ), BShow, true, i18n( "Show List" ) ); m_tags->setTitle( i18n( "Assigned Tags" ) ); m_lister->setRangeProvider( this ); // wee // m_lister->setOpenToplevel( true ); m_description->setPaper( TQBrush( colorGroup().background() ) ); connect( m_toolbar->getButton( BShow ), TQT_SIGNAL( clicked() ), this, TQT_SIGNAL( showList() ) ); connect( m_toolbar->getButton( BBack ), TQT_SIGNAL( clicked() ), this, TQT_SIGNAL( back() ) ); connect( m_toolbar->getButton( BForward ), TQT_SIGNAL( clicked() ), this, TQT_SIGNAL( forward() ) ); connect( m_lister, TQT_SIGNAL( detailsRequested( Lister::Entity ) ), this, TQT_SIGNAL( detailsRequested( Lister::Entity ) ) ); observeComponent< component::State >(); adjustFontSize( m_name, 1 ); Cache &c = cache::Global::get( m_cache ); component::Packages::iterator i = c.packages().packagesBegin(); while ( !i->hasVersion() ) ++i; // ha hum... setPackage( *i ); } Lister::Range PackageDetails::listerRange() { utils::Range< entity::Relation > r = m_package.depends(); utils::VectorRange< entity::Entity > vr; while ( r != r.end() ) { if ( !r->targetPackages().empty() ) std::cerr << r->targetPackages()->name() << std::endl; vr.consume( *r ); r = r.next(); } return vr.sorted(); } void PackageDetails::loadFileListWorker() { entity::Package p = m_package; std::string fl, flfile = "/var/lib/dpkg/info/" + p.name() + ".list"; std::ifstream ifl( flfile.c_str() ); int i = 0; kdDebug() << "PackageDetails::loadFileListWorker() entering loop" << endl; while ( ifl.is_open() && !ifl.eof() ) { std::string line; getline( ifl, line ); if ( line == "/." || line == "" ) continue; // nasty evil thing go away m_qtMutex.lock(); KURL url( "file:///" ); url.addPath( u8( line ) ); KFileItem *it = new KFileItem( url, u8( "" ), 0 ); it->setName( u8( line ) ); m_fileList->insertItem( it ); ++i; m_qtMutex.unlock(); } kdDebug() << "PackageDetails::loadFileListWorker() leaving loop" << endl; ifl.close(); } void PackageDetails::notifyPreRebuild( component::Base * ) { kdDebug() << "PackageDetails::notifyPreRebuild()" << endl; Threads::wait(); m_logical->setEnabled( false ); m_remove->setEnabled( false ); m_logical->disconnect( TQT_SIGNAL( clicked() ) ); m_remove->disconnect( TQT_SIGNAL( clicked() ) ); delete m_logicalAct; delete m_removeAct; kdDebug() << "PackageDetails::notifyPreRebuild() done" << endl; } void PackageDetails::loadFileList() { Cache &c = cache::Global::get( m_cache ); if ( m_fileListRunning || !c.isOpen() ) { TQTimer::singleShot( 100, this, TQT_SLOT( loadFileList() ) ); return; } kdDebug() << "PackageDetails::loadFileList()" << endl; m_fileListRunning = true; // the following call is neccessary to invoke buildDefaultType of KMimeType // the first time the method is called it will check for // existence of application/octet-stream and *popup a dialog* if // not found -- we don't want that to happen in a non-gui thread KMimeType::defaultMimeTypePtr(); m_thread = asyncCall( std::mem_fun( &PackageDetails::loadFileListWorker ), this ); m_qtMutex.lock(); m_fileList->KFileView::clear(); c.progress().OverallProgress( 0, 0, 0, i18n( "Loading filelist..." ).ascii() ); m_qtMutex.unlock(); Threads::enqueue( m_thread, &m_qtMutex ); Threads::wait(); c.progress().Done(); m_fileListRunning = false; kdDebug() << "PackageDetails::loadFileList() finished" << endl; } void PackageDetails::setPackage( cache::entity::Package p ) { kdDebug() << "PackageDetails::setPackage()" << endl; m_package = p.stable(); m_name->setText( TQString( "" ) + p.name( std::string( "No package" ) ) + "" ); m_info->setPackage( p ); TQString l = u8( p.longDescription( std::string( i18n( "No long description available" ).local8Bit() ) ) ); m_description->setText( TQString( "" ) + formatLongDescription( l ) + "" ); std::string na = u8( i18n( "not available" ) ); m_tags->setTags( p.tags( entity::Package::TagSet() ) ); m_tags->openToplevel(); m_architecture->setText( labelFormat( i18n( "Architecture: " ), p.architecture( na ) ) ); m_filename->setText( labelFormat( i18n( "Filename: " ), p.fileName( na ) ) ); m_md5->setText( labelFormat( i18n( "MD5: " ), p.md5sum( na ) ) ); m_source->setText( labelFormat( i18n( "Source Package: " ), p.source( na ) ) ); /* IF IT ISN'T KUBUNTU, DON'T SUPPORT CHANGELOGS! */ #ifdef KUBUNTU // Lets go ahead and stick the changelog in there.... try { global_changelog->setParent(p); m_changelog->setText(i18n("Loading...")); connect(dynamic_cast(global_changelog), TQT_SIGNAL( changelogReady(TQString) ), dynamic_cast(this), TQT_SLOT( changelogDisplay(TQString) )); connect(dynamic_cast(this), TQT_SIGNAL( requestTheChangelog() ), dynamic_cast(global_changelog), TQT_SIGNAL( changelogNeeded() )); emit requestTheChangelog(); } catch (...) {}; #endif /* KUBUNTU */ notifyPostChange( 0 ); m_lister->cleanRebuild(); loadFileList(); } void PackageDetails::changelogDisplay( TQString content ) { m_changelog->setText(content); } void PackageDetails::notifyPostChange( cache::component::Base * ) { kdDebug() << "PackageDetails::notifyPostChange()" << endl; // 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 PackageDetails::notifyPostRebuild( cache::component::Base *b ) { kdDebug() << "PackageDetails::notifyPostRebuild( " << b << " )" << endl; // can't call directly because stable entities are not guaranteed // to be stabilised at this point yet TQTimer::singleShot( 0, this, TQT_SLOT( updateLogical() ) ); TQTimer::singleShot( 0, this, TQT_SLOT( loadFileList() ) ); m_lister->cleanRebuild(); } void PackageDetails::updateLogical() { Cache &c = cache::Global::get( m_cache ); if ( !c.isOpen() ) { TQTimer::singleShot( 100, this, TQT_SLOT( updateLogical() ) ); return; } kdDebug() << "PackageDetails::updateLogical()" << endl; entity::Package p = m_package; kdDebug() << "PackageDetails::updateLogical: p = " << p.name() << " p.component() = " << &p.component() << endl; if ( !p.valid() ) return; // nothing to update EntityActor *a = 0, *b = 0; if ( p.canUpgrade() ) { a = new EntityActor( p.upgrade() ); } else if ( p.canInstall() ) { a = new EntityActor( p.install() ); } else if ( p.canKeep() ) { a = new EntityActor( p.keep() ); } if ( p.canRemove() ) { b = new EntityActor( p.remove() ); } if ( a ) { m_logical->setEnabled( true ); m_logical->setText( u8( a->actor().prettyName() ) ); connect( m_logical, TQT_SIGNAL( clicked() ), a, TQT_SLOT( destructiveAct() ) ); } else { m_logical->setText( i18n( "Install" ) ); m_logical->setEnabled( false ); } if ( b ) { m_remove->setEnabled( true ); m_remove->setText( u8( b->actor().prettyName() ) ); connect( m_remove, TQT_SIGNAL( clicked() ), b, TQT_SLOT( destructiveAct() ) ); } else { m_remove->setText( i18n( "Remove" ) ); m_remove->setEnabled( false ); } m_logicalAct = a; m_removeAct = b; // std::copy( r, r.last(), vr ); // r.consume( utils::upcastRange< entity::Entity >( p.depends() ) ); } void PackageDetails::setHasForward( bool e ) { m_toolbar->setItemEnabled( BForward, e ); // m_forward->setEnabled( e ); } void PackageDetails::setHasBack( bool e ) { m_toolbar->setItemEnabled( BBack, e ); // m_back->setEnabled( e ); }