Logo Search packages:      
Sourcecode: adept version File versions  Download package

packagedetails.cpp

#include <qtoolbutton.h>
#include <qtextbrowser.h>
#include <qlabel.h>
#include <klocale.h>
#include <kiconloader.h>
#include <qpushbutton.h>
#include <ktoolbar.h>
#include <ktoolbarbutton.h>

#include <kfileitem.h>
#include <kfiledetailview.h>
#include <kapplication.h>

#include <adept/lister.h>
#include <adept/tagchooser.h>
#include <adept/packageinfo.h>
#include <adept/packagedetails.h>
#include <adept/utils.h>

#include <fstream>

using namespace adept;

PackageDetails::PackageDetails( QWidget *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( KToolBar::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( QBrush( colorGroup().background() ) );

    connect( m_toolbar->getButton( BShow ), SIGNAL( clicked() ),
             this, SIGNAL( showList() ) );
    connect( m_toolbar->getButton( BBack ), SIGNAL( clicked() ),
             this, SIGNAL( back() ) );
    connect( m_toolbar->getButton( BForward ), SIGNAL( clicked() ),
             this, SIGNAL( forward() ) );
    connect( m_lister, SIGNAL( detailsRequested( Lister::Entity ) ),
             this, 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( SIGNAL( clicked() ) );
    m_remove->disconnect( 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() ) {
        QTimer::singleShot( 100, this, 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..." ) );

    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( QString( "<b>" ) +
                     p.name( std::string( "No package" ) ) + "</b>" );
    m_info->setPackage( p );
    QString l = p.longDescription(
        std::string( i18n( "No long description available" ).local8Bit() ) );
    m_description->setText( QString( "<qt>" )
                            + formatLongDescription( l ) + "</qt>" );

    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 ) ) );


    notifyPostChange( 0 );
    m_lister->cleanRebuild();
    loadFileList();
}

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
    QTimer::singleShot( 0, this, 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
    QTimer::singleShot( 0, this, SLOT( updateLogical() ) );
    QTimer::singleShot( 0, this, SLOT( loadFileList() ) );
    m_lister->cleanRebuild();
}

void PackageDetails::updateLogical()
{
    Cache &c = cache::Global::get( m_cache );
    if ( !c.isOpen() ) {
        QTimer::singleShot( 100, this, 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, SIGNAL( clicked() ),
                 a, 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, SIGNAL( clicked() ),
                 b, 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 );
}

Generated by  Doxygen 1.6.0   Back to index