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

acqprogress.cpp

// -*- C++ -*-

#include <qprogressbar.h>
#include <klistview.h>
#include <kapplication.h>
#include <qpainter.h>
#include <qpixmap.h>
#include <qstyle.h>
#include <kmessagebox.h>
#include <klocale.h>
#include <kdebug.h>

#include "acqprogress.h"
#include <apt-pkg/acquire-item.h>
#include <apt-pkg/acquire-worker.h>
#include <apt-pkg/strutl.h>
#include <apt-pkg/error.h>
#include <apt-pkg/configuration.h>

#include <adept/utils.h>

#include <stdio.h>
#include <signal.h>
#include <iostream>

#define _(a...) (a) // XXX

using namespace std;

namespace adept {

AcqStatus::Item::Item (KListView *parent, pkgAcquire::ItemDesc &item, bool hit)
: KListViewItem( parent )
{
    m_pbcol = 0;
    m_prog = new ItemProgress( 0, 0 );
    m_prog->setStatus( "waiting" );
    m_prog->setTotalSteps( 100 );
    m_item = item;
    m_id = m_item.Owner->ID;
    /* if (item.Owner->FileSize > 0)
       setText( 1, SizeToStr( item.Owner->FileSize ).c_str() + QString( "B" ) ); */
    setText( 1, u8( item.Description ) );
    // cerr << "create: id = " << item . Owner -> ID << ", myId = " << m_item . Owner -> ID << endl;
    if (hit) {
        m_prog->setStatus( "hit" );
    } else
        m_prog->setStatus( "waiting" );
    // QString (SizeToStr (Itm.Owner -> FileSize) . c_str ()) + QString ("B"),
    // /* QString (Itm . Owner -> ID) + */ QString (Itm.Description . c_str ()));
}

AcqStatus::Item::~Item ()
{
    delete m_prog;
}

int AcqStatus::Item::compare (QListViewItem *i, int /*col*/, bool /*ascend*/) const
{
    int id1 = m_id;
    int id2 = ((Item *) i) -> m_id;
    return (id2 >= id1) - (id2 <= id1);
}

void AcqStatus::Item::pulse (pkgAcquire::Worker *w)
{
    if (w) {
        if (w->TotalSize)
            setStatus( "progress", long( double(
                                   w -> CurrentSize * 100.0)
                               / double( w->TotalSize ) ) );
        else
            setStatus( "downloading", 0 );
    }
}

void AcqStatus::Item::setStatus( const std::string &s, int i )
{
    m_prog->setStatus( s, i );
}

void AcqStatus::Item::paintCell (QPainter *p, const QColorGroup &cg,
        int column, int width, int alignment )
{
    QColorGroup _cg( cg );
    QColor c = _cg.text();

    if ( column == m_pbcol ) {
        const QRect bar = QRect( 0, 0, width, height() );
        m_prog->resize( width, height() );
        QPixmap pm = QPixmap::grabWidget( m_prog );
        // p->fillRect( bar, listView()->paletteBackgroundColor() );
        p->drawPixmap( bar.x(), bar.y(), pm );
    } else {
        QPixmap pm( width, height() );
        QPainter _p( &pm );
        _cg.setColor( QColorGroup::Text, c );
        KListViewItem::paintCell( &_p, _cg, column, width, alignment );
        p->drawPixmap( 0, 0, pm );
    }
}

AcqStatus::Item *AcqStatus::findItem (pkgAcquire::ItemDesc &Itm)
{
    if ( Itm.Owner->ID < m_idOffset )
        return 0;
    if ( Itm.Owner->ID - m_idOffset >= m_items.size() )
        return 0;
    return m_items[ Itm.Owner->ID - m_idOffset ];
}

AcqStatus::AcqStatus(QWidget *parent, const char *name)
    : KListView (parent, name), m_idOffset( 0 ), m_continue( true )
{
    // m_lastItem = 0;
    addColumn( i18n( "Progress" ) );
    addColumn( i18n( "Description" ) );
    setSorting (1);
    setColumnWidth (0, 220);
    setColumnWidth (1, 300);
    setResizeMode (LastColumn);
    ID = 0;
}

void AcqStatus::Done (pkgAcquire::ItemDesc &Itm)
{
    Item *i = findItem (Itm);
    if (i) {
        i->setStatus( "done" );
    }
    emit statusChanged( StWaiting );
    triggerUpdate();
    KApplication::kApplication()->processEvents();
}

void AcqStatus::clear()
{
    KListView::clear();
    m_idOffset += m_items.size();
    m_items.clear(); // got deleted by klistview already
}

void AcqStatus::Start()
{
    clear();
    pkgAcquireStatus::Start();
    kdDebug() << "AcqStatus::Start ()" << endl;
    _config -> Set ("APT::Fetcher::Select-Timeout-Usec", 100000);
    emit statusChanged( StWaiting );
    triggerUpdate();
    KApplication::kApplication()->processEvents();
}

void AcqStatus::IMSHit(pkgAcquire::ItemDesc &Itm)
{
    Itm.Owner->ID = ID++;
    Item *i = new Item( this, Itm, true );
    // ensureItemVisible( i );
    i->setStatus( "hit" );
    m_items.push_back( i );

    kdDebug() << "imshit called on ID = " << ID - 1 << " i = " << (void *)i << endl;
    triggerUpdate();
    KApplication::kApplication()->processEvents();
};

void AcqStatus::Fetch(pkgAcquire::ItemDesc &Itm)
    // an item started to download
{
    Update = true;
    if (Itm.Owner->Complete == true) // XXX?
        return;

    Itm.Owner->ID = ID++;

    Item *i = new Item( this, Itm );
    // ensureItemVisible( i );
    m_items.push_back( i );

    kdDebug() << "fetch called on ID = " << ID - 1 << " i = " << (void *)i << endl;
    emit statusChanged( StDownloading );
    triggerUpdate();
    KApplication::kApplication()->processEvents();
};

void AcqStatus::Fail(pkgAcquire::ItemDesc &Itm)
    // item failed to download
{
    kdDebug() << "fail, status = " << Itm.Owner->Status
              << " ID = " << Itm.Owner->ID << endl;
    // Ignore certain kinds of transient failures (bad code)
    if (Itm.Owner->Status == pkgAcquire::Item::StatIdle) {
        kdDebug() << "fail with StatIdle, ignoring" << endl;
        return;
    }

    Item *i = findItem (Itm);
    kdDebug() << "fail, i = " << i << endl;
    if (! i)
        return;
    if (Itm.Owner->Status == pkgAcquire::Item::StatDone) {
        i->setStatus( "ignored" );
    } else {
        i->setStatus( "error" );
    }

    triggerUpdate();
    KApplication::kApplication()->processEvents();
};

void AcqStatus::Stop()
{
    pkgAcquireStatus::Stop();
    emit statusChanged( StDone );
    triggerUpdate ();
    KApplication::kApplication()->processEvents();
}

bool AcqStatus::Pulse(pkgAcquire *Owner)
{
    pkgAcquireStatus::Pulse(Owner);

    for (pkgAcquire::Worker *I = Owner->WorkersBegin(); I != 0;
         I = Owner->WorkerStep(I)) {
        if (I -> CurrentItem) {
            Item *i = findItem (* (I -> CurrentItem));
            if (i)
                i -> pulse (I);
        }
    }
    
    triggerUpdate ();
    // repaint ();
    
    if (TotalBytes > 0)
        emit totalProgress(
            long( double(
                      (CurrentBytes +
                       CurrentItems)*100.0)/double(TotalBytes+TotalItems) ) );
    else
        emit totalProgress (-1);
    KApplication::kApplication () -> processEvents ();

    if ( m_continue )
        return true;

    m_continue = true;
    return false;
}

bool AcqStatus::MediaChange(string Media,string Drive)
{
    int res = KMessageBox::warningContinueCancel(
        this, i18n( "Please insert the disc "
                    "labeled '%1' in the drive "
                    "'%2' and press enter" ).arg(
                        u8( Media ) ).arg( u8( Drive ) ),
        i18n( "Media Change" ) );
    if ( res == KMessageBox::Cancel )
        cancel();
   return true; 
}

void AcqStatus::cancel()
{
    m_continue = false;
}

AcqStatusDialog::AcqStatusDialog (QWidget *parent, const char *name, bool modal)
    : KDialogBase( parent, name, modal,
                   u8( "progress dialog (FIXME: waiting for headers, done)" ),
                   Ok|Cancel, Cancel, true )
{
    m_status = new AcqStatus (this, "");
    setMainWidget( m_status.data() );
    enableButton (Ok, false);
    connect (m_status.data(), SIGNAL (statusChanged (AcqStatus::Status)),
             this, SLOT (statusChange (AcqStatus::Status)));
}

void AcqStatusDialog::statusChange (AcqStatus::Status st)
{
    if (st == AcqStatus::StDownloading || st == AcqStatus::StWaiting) {
        enableButton (Ok, false);
        // XXX: cancel should be true; but needs implementation first
        enableButton (Cancel, false);
    } else if (st == AcqStatus::StDone) {
        enableButton (Ok, true);
        enableButton (Cancel, false);
    }
}

}

#include "acqprogress.moc"

Generated by  Doxygen 1.6.0   Back to index