/*************************************************************************** transferentry.cpp - description ------------------- begin : Wed Nov 3 2004 copyright : (C) 2004 by Diederik van der Boor email : vdboor --at-- codingdomain.com ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "transferentry.h" #include "../kmessdebug.h" #include <QPixmap> #include <KLocale> #include <KRun> #include <KIconLoader> #include <KMimeType> #include <KUrl> // Constructor TransferEntry::TransferEntry( QWidget *parent, const QString filename, const ulong filesize, bool incoming, const QImage preview) : QWidget( parent ), Ui::TransferEntry(), isDone_(false), incoming_(incoming), filename_(filename), filesize_(filesize), previousPercentage_(-1), previousTransferred_(0), transferID_(-1) { // Set up the user interface setupUi( this ); // Get the preview from the caller preview_ = QPixmap::fromImage( preview ); #ifdef KMESSDEBUG_TRANSFERENTRY kmDebug() << "Initializing, file='" << filename_ << "', preview=" << ( preview_.isNull() ? "null" : "set" ) << "." << endl; #endif KIconLoader *loader = KIconLoader::global(); // Set pixmap and filename if( preview_.isNull() ) { // Get a default icon pixmap QString iconTitle( KMimeType::iconNameForUrl( KUrl( filename_) ) ); preview_ = loader->loadIcon( iconTitle, KIconLoader::NoGroup, iconLabel_->width() ); if( ! preview_.isNull() ) { iconLabel_->setPixmap( preview_ ); } } else { // Scale down if needed. Don't scale large images up if( preview_.width() > iconLabel_->width() || preview_.height() > iconLabel_->height() ) { preview_ = preview_.scaled( iconLabel_->width(), iconLabel_->height(), Qt::KeepAspectRatio, Qt::SmoothTransformation ); } iconLabel_->setPixmap( preview_ ); } filenameLabel_->setText("<b>" + filename_ + "</b>"); QPixmap pixmapTransfer; // Enable urls? if(incoming_) { // Can't open it yet. openLabel_->hide(); openLabel_->setEnabled(false); pixmapTransfer = loader->loadIcon( "go-down", KIconLoader::Small ); } else { pixmapTransfer = loader->loadIcon( "go-up", KIconLoader::Small ); } cancelLabel_->setEnabled(true); iconTransferLabel_->setPixmap( pixmapTransfer ); // Set the timer to update the transfer rate and eta timer_ = new QTimer(); connect( timer_ , SIGNAL( timeout() ), this, SLOT( updateTransferRate() ) ); } // Destructor TransferEntry::~TransferEntry() { #ifdef KMESSDEBUG_TRANSFERENTRY kmDebug() << "DESTROYED. [file=" << filename_ << "]"; #endif delete timer_; } // Called when cancel is clicked. void TransferEntry::cancelClicked() { #ifdef KMESSDEBUG_TRANSFERENTRY kmDebug() << "Notifying listeners."; #endif emit cancelTransfer( transferID_ ); if(! isDone_) { // If a slot didn't call failTransfer(), // we do this with the correct (!) status message. failTransfer( i18n("Cancelled") ); } } // Indicate the transfer is complete or cancelled. bool TransferEntry::isDone() const { return isDone_; } // Returns true if the transfer is incoming bool TransferEntry::isIncoming() const { return incoming_; } // Return the file name QString TransferEntry::getFileName() const { return filename_; } // Mark the transfer as failed void TransferEntry::failTransfer( const QString &message ) { if( isDone_ ) { #ifdef KMESSDEBUG_TRANSFERENTRY kmDebug() << "already done."; #endif return; } #ifdef KMESSDEBUG_TRANSFERENTRY kmDebug() << "Displaying error message."; #endif // Update the widgets if(message == 0 || message.isEmpty()) { statusLabel_->setText( i18n("Failed!") ); } else { statusLabel_->setText( message ); } timer_->stop(); // Make sure the widget does not resize when the progressbar hides setMinimumHeight( height() ); progressBar_->hide(); cancelLabel_->setEnabled(false); cancelLabel_->hide(); isDone_ = true; } // Mark the transfer as complete void TransferEntry::finishTransfer() { #ifdef KMESSTEST KMESS_ASSERT( ! isDone_ ); #endif if( isDone_ ) { #ifdef KMESSDEBUG_TRANSFERENTRY kmDebug() << "already done."; #endif return; } #ifdef KMESSDEBUG_TRANSFERENTRY kmDebug() << "Displaying success message."; #endif // Make sure the widget does not resize when the progressbar hides setMinimumHeight( height() ); // Update the widgets statusLabel_->setText( i18n("Completed") ); progressBar_->hide(); cancelLabel_->setEnabled(false); cancelLabel_->hide(); openLabel_ ->setEnabled(true); openLabel_ ->show(); timer_ ->stop(); isDone_ = true; } // Called when open is clicked void TransferEntry::openClicked() { // The file:// prefix must be followed by a full path if( ! filename_.startsWith( "file://" ) ) { new KRun( "file://" + filename_, window() ); } else { new KRun( filename_, window() ); } } // Set the transfer ID to identify ourselves to the Transfer Window void TransferEntry::setTransferID( int transferID ) { transferID_ = transferID; } // Convert a string to some more readable form QString TransferEntry::toReadableBytes( ulong bytes ) { QString format; if(bytes > 1048576) { // Using '%.2f' instead of '%.1f' removes the ".0" part, but it's less pretty. format.sprintf("%.1f", (double) bytes / 1048576.0); return i18n( "%1 MB", format ); } else if(bytes > 1024) { format.sprintf("%.1f", (double) bytes / 1024.0); return i18n( "%1 kB", format ); } else { return i18n( "%1 bytes", bytes ); } } // Set a status message void TransferEntry::setStatusMessage( const QString &message ) { #ifdef KMESSTEST KMESS_ASSERT( ! isDone_ ); #endif if( isDone_ ) { #ifdef KMESSDEBUG_TRANSFERENTRY kmDebug() << "already done."; #endif return; } #ifdef KMESSDEBUG_TRANSFERENTRY kmDebug() << "displaying '" << message << "'."; #endif statusLabel_->setText( message ); } // Update the progress bar void TransferEntry::updateProgress( ulong bytesTransferred ) { #ifdef KMESSTEST KMESS_ASSERT( ! isDone_ ); #endif if( isDone_ ) { #ifdef KMESSDEBUG_TRANSFERENTRY kmDebug() << "already done."; #endif return; } // Start the ETA timer if it hasn't already if( ! timer_->isActive() ) { timer_->start( 3000 ); } bytesTransferred_ = bytesTransferred; int percent = (int) ( ( (double) bytesTransferred * 100.0 ) / (double) filesize_ ); QString transferred( toReadableBytes( bytesTransferred ) ); QString total ( toReadableBytes( filesize_ ) ); // Avoid useless repaints if( ! ( percent == previousPercentage_ ) ) { previousPercentage_ = percent; progressBar_->setValue( percent ); } #ifdef KMESSDEBUG_TRANSFERENTRY kmDebug() << "transfer is at " << ((float)percent/10) << " percent."; #endif if( incoming_ ) { statusText_ = i18n( "%1 of %2 received.", transferred, total ); } else { statusText_ = i18n( "%1 of %2 sent.", transferred, total ); } statusLabel_->setText( statusText_ + " " + speedText_ ); } // Update the transfer rate and ETA void TransferEntry::updateTransferRate() { // To avoid to works with different transferred bytes ulong tempTransferred = bytesTransferred_; // Calculate the bytes transferred from the last calling ulong bytesTransferredFromLast = tempTransferred - previousTransferred_; QString speed, eta; // Approximate the speed with the timeout of timer (3) int bytesSpeed = (int)( bytesTransferredFromLast / 3 ); int currentEta; // Verify if the bytesSpeed is 0 if( ! ( bytesSpeed == 0 ) ) { currentEta = (int) ( ( filesize_ - tempTransferred ) / bytesSpeed ); QTime timeEta; eta = timeEta.addSecs( currentEta ).toString(); previousTransferred_ = tempTransferred; } else { // Is impossible to calculate ETA eta = i18n( "infinite" ); } speedText_ = QString("Speed: %1, ETA: %2").arg( toReadableBytes( bytesSpeed ) ).arg( eta ); statusLabel_->setText( statusText_ + " " + speedText_ ); } #include "transferentry.moc"