kio Library API Documentation

defaultprogress.cpp

00001 /* This file is part of the KDE libraries
00002    Copyright (C) 2000 Matej Koss <koss@miesto.sk>
00003 
00004    This library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Library General Public
00006    License version 2 as published by the Free Software Foundation.
00007 
00008    This library is distributed in the hope that it will be useful,
00009    but WITHOUT ANY WARRANTY; without even the implied warranty of
00010    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011    Library General Public License for more details.
00012 
00013    You should have received a copy of the GNU Library General Public License
00014    along with this library; see the file COPYING.LIB.  If not, write to
00015    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00016    Boston, MA 02111-1307, USA.
00017 */
00018 
00019 #include <qtimer.h>
00020 #include <qlayout.h>
00021 #include <qtooltip.h>
00022 #include <qdatetime.h>
00023 #include <qcheckbox.h>
00024 
00025 #include <kapplication.h>
00026 #include <kdebug.h>
00027 #include <kdialog.h>
00028 #include <kstringhandler.h>
00029 #include <kglobal.h>
00030 #include <klocale.h>
00031 #include <kiconloader.h>
00032 #include <kprocess.h>
00033 #include <kpushbutton.h>
00034 #include <kstandarddirs.h>
00035 #include <kstdguiitem.h>
00036 #include <klineedit.h>
00037 
00038 #ifdef Q_WS_X11
00039 #include <kwin.h>
00040 #endif
00041 
00042 #include "jobclasses.h"
00043 #include "defaultprogress.h"
00044 
00045 namespace KIO {
00046 
00047 class DefaultProgress::DefaultProgressPrivate
00048 {
00049 public:
00050   bool keepOpenChecked;
00051   bool noCaptionYet;
00052   KPushButton *cancelClose;
00053   KPushButton *openFile;
00054   KPushButton *openLocation;
00055   QCheckBox   *keepOpen;
00056   KURL        location;
00057   QTime       startTime;
00058 };
00059 
00060 DefaultProgress::DefaultProgress( bool showNow )
00061   : ProgressBase( 0 ),
00062   m_iTotalSize(0), m_iTotalFiles(0), m_iTotalDirs(0),
00063   m_iProcessedSize(0), m_iProcessedDirs(0), m_iProcessedFiles(0)
00064 {
00065   init();
00066 
00067   if ( showNow ) {
00068     show();
00069   }
00070 }
00071 
00072 DefaultProgress::DefaultProgress( QWidget* parent, const char* /*name*/ )
00073   : ProgressBase( parent ),
00074   m_iTotalSize(0), m_iTotalFiles(0), m_iTotalDirs(0),
00075   m_iProcessedSize(0), m_iProcessedDirs(0), m_iProcessedFiles(0)
00076 {
00077     init();
00078 }
00079 
00080 bool DefaultProgress::keepOpen() const
00081 {
00082     return d->keepOpenChecked;
00083 }
00084 
00085 void DefaultProgress::init()
00086 {
00087   d = new DefaultProgressPrivate;
00088 
00089 #ifdef Q_WS_X11 //FIXME(E): Remove once all the KWin::foo calls have been ported to QWS
00090   // Set a useful icon for this window!
00091   KWin::setIcons( winId(),
00092           KGlobal::iconLoader()->loadIcon( "filesave", KIcon::NoGroup, 32 ),
00093           KGlobal::iconLoader()->loadIcon( "filesave", KIcon::NoGroup, 16 ) );
00094 #endif
00095 
00096   QVBoxLayout *topLayout = new QVBoxLayout( this, KDialog::marginHint(),
00097                                             KDialog::spacingHint() );
00098   topLayout->addStrut( 360 );   // makes dlg at least that wide
00099 
00100   QGridLayout *grid = new QGridLayout( 2, 3 );
00101   topLayout->addLayout(grid);
00102   grid->addColSpacing(1, KDialog::spacingHint());
00103   // filenames or action name
00104   grid->addWidget(new QLabel(i18n("Source:"), this), 0, 0);
00105 
00106   sourceEdit = new KLineEdit(this);
00107   sourceEdit->setReadOnly(true);
00108   sourceEdit->setEnableSqueezedText(true);
00109   grid->addWidget(sourceEdit, 0, 2);
00110 
00111   destInvite = new QLabel(i18n("Destination:"), this);
00112   grid->addWidget(destInvite, 1, 0);
00113 
00114   destEdit = new KLineEdit(this);
00115   destEdit->setReadOnly (true);
00116   destEdit->setEnableSqueezedText(true);
00117   grid->addWidget(destEdit, 1, 2);
00118 
00119   m_pProgressBar = new KProgress(this);
00120   topLayout->addWidget( m_pProgressBar );
00121 
00122   // processed info
00123   QHBoxLayout *hBox = new QHBoxLayout();
00124   topLayout->addLayout(hBox);
00125 
00126   sizeLabel = new QLabel(this);
00127   hBox->addWidget(sizeLabel);
00128 
00129   resumeLabel = new QLabel(this);
00130   hBox->addWidget(resumeLabel);
00131 
00132   progressLabel = new QLabel( this );
00133 /*  progressLabel->setSizePolicy( QSizePolicy( QSizePolicy::MinimumExpanding,
00134                                              QSizePolicy::Preferred ) );*/
00135   progressLabel->setAlignment( QLabel::AlignRight );
00136   hBox->addWidget( progressLabel );
00137 
00138   hBox = new QHBoxLayout();
00139   topLayout->addLayout(hBox);
00140 
00141   speedLabel = new QLabel(this);
00142   hBox->addWidget(speedLabel, 1);
00143 
00144   QFrame *line = new QFrame( this );
00145   line->setFrameShape( QFrame::HLine );
00146   line->setFrameShadow( QFrame::Sunken );
00147   topLayout->addWidget( line );
00148 
00149   d->keepOpen = new QCheckBox( i18n("&Keep this window open after transfer is complete"), this);
00150   connect( d->keepOpen, SIGNAL( toggled(bool) ), SLOT( slotKeepOpenToggled(bool) ) );
00151   topLayout->addWidget(d->keepOpen);
00152   d->keepOpen->hide();
00153 
00154   hBox = new QHBoxLayout();
00155   topLayout->addLayout(hBox);
00156 
00157   d->openFile = new KPushButton( i18n("Open &File"), this );
00158   connect( d->openFile, SIGNAL( clicked() ), SLOT( slotOpenFile() ) );
00159   hBox->addWidget( d->openFile );
00160   d->openFile->setEnabled(false);
00161   d->openFile->hide();
00162 
00163   d->openLocation = new KPushButton( i18n("Open &Destination"), this );
00164   connect( d->openLocation, SIGNAL( clicked() ), SLOT( slotOpenLocation() ) );
00165   hBox->addWidget( d->openLocation );
00166   d->openLocation->hide();
00167 
00168   hBox->addStretch(1);
00169 
00170   d->cancelClose = new KPushButton( KStdGuiItem::cancel(), this );
00171   connect( d->cancelClose, SIGNAL( clicked() ), SLOT( slotStop() ) );
00172   hBox->addWidget( d->cancelClose );
00173 
00174   resize( sizeHint() );
00175   setMaximumHeight(sizeHint().height());
00176 
00177   d->keepOpenChecked = false;
00178   d->noCaptionYet = true;
00179   setCaption(i18n("Progress Dialog")); // show something better than kio_uiserver
00180 }
00181 
00182 DefaultProgress::~DefaultProgress()
00183 {
00184   delete d;
00185 }
00186 
00187 void DefaultProgress::slotTotalSize( KIO::Job*, KIO::filesize_t bytes )
00188 {
00189   if ( m_iTotalSize == bytes )
00190       return;
00191   m_iTotalSize = bytes;
00192   if (d->startTime.isNull())
00193     d->startTime.start();
00194 }
00195 
00196 
00197 void DefaultProgress::slotTotalFiles( KIO::Job*, unsigned long files )
00198 {
00199   if ( m_iTotalFiles == files )
00200       return;
00201   m_iTotalFiles = files;
00202   showTotals();
00203 }
00204 
00205 
00206 void DefaultProgress::slotTotalDirs( KIO::Job*, unsigned long dirs )
00207 {
00208   if ( m_iTotalDirs == dirs )
00209       return;
00210   m_iTotalDirs = dirs;
00211   showTotals();
00212 }
00213 
00214 void DefaultProgress::showTotals()
00215 {
00216   // Show the totals in the progress label, if we still haven't
00217   // processed anything. This is useful when the stat'ing phase
00218   // of CopyJob takes a long time (e.g. over networks).
00219   if ( m_iProcessedFiles == 0 && m_iProcessedDirs == 0 )
00220   {
00221     QString tmps;
00222     if ( m_iTotalDirs > 1 )
00223       // that we have a singular to translate looks weired but is only logical
00224       tmps = i18n("%n folder", "%n folders", m_iTotalDirs) + "   ";
00225     tmps += i18n("%n file", "%n files", m_iTotalFiles);
00226     progressLabel->setText( tmps );
00227   }
00228 }
00229 
00230 //static
00231 QString DefaultProgress::makePercentString( unsigned long percent,
00232                                             KIO::filesize_t totalSize,
00233                                             unsigned long totalFiles )
00234 {
00235   if ( totalSize )
00236       return i18n( "%1 % of %2 " ).arg( percent ).arg( KIO::convertSize( totalSize ) );
00237   else if ( totalFiles )
00238       return i18n( "%1 % of 1 file", "%1 % of %n files", totalFiles ).arg( percent );
00239   else
00240       return i18n( "%1 %" ).arg( percent );
00241 }
00242 
00243 void DefaultProgress::slotPercent( KIO::Job*, unsigned long percent )
00244 {
00245   QString caption = makePercentString( percent, m_iTotalSize, m_iTotalFiles );
00246   m_pProgressBar->setValue( percent );
00247   switch(mode) {
00248   case Copy:
00249     caption.append(i18n(" (Copying)"));
00250     break;
00251   case Move:
00252     caption.append(i18n(" (Moving)"));
00253     break;
00254   case Delete:
00255     caption.append(i18n(" (Deleting)"));
00256     break;
00257   case Create:
00258     caption.append(i18n(" (Creating)"));
00259     break;
00260   case Done:
00261     caption.append(i18n(" (Done)"));
00262     break;
00263   }
00264 
00265   setCaption( caption );
00266   d->noCaptionYet = false;
00267 }
00268 
00269 
00270 void DefaultProgress::slotInfoMessage( KIO::Job*, const QString & msg )
00271 {
00272   speedLabel->setText( msg );
00273   speedLabel->setAlignment( speedLabel->alignment() & ~Qt::WordBreak );
00274 }
00275 
00276 
00277 void DefaultProgress::slotProcessedSize( KIO::Job*, KIO::filesize_t bytes ) {
00278   if ( m_iProcessedSize == bytes )
00279     return;
00280   m_iProcessedSize = bytes;
00281 
00282   QString tmp = i18n( "%1 of %2 complete")
00283                 .arg( KIO::convertSize(bytes) )
00284                 .arg( KIO::convertSize(m_iTotalSize));
00285   sizeLabel->setText( tmp );
00286 }
00287 
00288 
00289 void DefaultProgress::slotProcessedDirs( KIO::Job*, unsigned long dirs )
00290 {
00291   if ( m_iProcessedDirs == dirs )
00292     return;
00293   m_iProcessedDirs = dirs;
00294 
00295   QString tmps;
00296   tmps = i18n("%1 / %n folder", "%1 / %n folders", m_iTotalDirs).arg( m_iProcessedDirs );
00297   tmps += "   ";
00298   tmps += i18n("%1 / %n file", "%1 / %n files", m_iTotalFiles).arg( m_iProcessedFiles );
00299   progressLabel->setText( tmps );
00300 }
00301 
00302 
00303 void DefaultProgress::slotProcessedFiles( KIO::Job*, unsigned long files )
00304 {
00305   if ( m_iProcessedFiles == files )
00306     return;
00307   m_iProcessedFiles = files;
00308 
00309   QString tmps;
00310   if ( m_iTotalDirs > 1 ) {
00311     tmps = i18n("%1 / %n folder", "%1 / %n folders", m_iTotalDirs).arg( m_iProcessedDirs );
00312     tmps += "   ";
00313   }
00314   tmps += i18n("%1 / %n file", "%1 / %n files", m_iTotalFiles).arg( m_iProcessedFiles );
00315   progressLabel->setText( tmps );
00316 }
00317 
00318 
00319 void DefaultProgress::slotSpeed( KIO::Job*, unsigned long bytes_per_second )
00320 {
00321   if ( bytes_per_second == 0 ) {
00322     speedLabel->setText( i18n( "Stalled") );
00323   } else {
00324     speedLabel->setText( i18n( "%1/s ( %2 remaining )").arg( KIO::convertSize( bytes_per_second ))
00325         .arg( KIO::convertSeconds( KIO::calculateRemainingSeconds( m_iTotalSize, m_iProcessedSize, bytes_per_second ))) );
00326   }
00327 }
00328 
00329 
00330 void DefaultProgress::slotCopying( KIO::Job*, const KURL& from, const KURL& to )
00331 {
00332   if ( d->noCaptionYet ) {
00333     setCaption(i18n("Copy File(s) Progress"));
00334     d->noCaptionYet = false;
00335   }
00336   mode = Copy;
00337   sourceEdit->setText(from.prettyURL());
00338   setDestVisible( true );
00339   checkDestination( to );
00340   destEdit->setText(to.prettyURL());
00341 }
00342 
00343 
00344 void DefaultProgress::slotMoving( KIO::Job*, const KURL& from, const KURL& to )
00345 {
00346   if ( d->noCaptionYet ) {
00347     setCaption(i18n("Move File(s) Progress"));
00348     d->noCaptionYet = false;
00349   }
00350   mode = Move;
00351   sourceEdit->setText(from.prettyURL());
00352   setDestVisible( true );
00353   checkDestination( to );
00354   destEdit->setText(to.prettyURL());
00355 }
00356 
00357 
00358 void DefaultProgress::slotCreatingDir( KIO::Job*, const KURL& dir )
00359 {
00360   if ( d->noCaptionYet ) {
00361     setCaption(i18n("Creating Folder"));
00362     d->noCaptionYet = false;
00363   }
00364   mode = Create;
00365   sourceEdit->setText(dir.prettyURL());
00366   setDestVisible( false );
00367 }
00368 
00369 
00370 void DefaultProgress::slotDeleting( KIO::Job*, const KURL& url )
00371 {
00372   if ( d->noCaptionYet ) {
00373     setCaption(i18n("Delete File(s) Progress"));
00374     d->noCaptionYet = false;
00375   }
00376   mode = Delete;
00377   sourceEdit->setText(url.prettyURL());
00378   setDestVisible( false );
00379 }
00380 
00381 void DefaultProgress::slotTransferring( KIO::Job*, const KURL& url )
00382 {
00383   if ( d->noCaptionYet ) {
00384     setCaption(i18n("Loading Progress"));
00385     d->noCaptionYet = false;
00386   }
00387   sourceEdit->setText(url.prettyURL());
00388   setDestVisible( false );
00389 }
00390 
00391 void DefaultProgress::slotStating( KIO::Job*, const KURL& url )
00392 {
00393   setCaption(i18n("Examining File Progress"));
00394   sourceEdit->setText(url.prettyURL());
00395   setDestVisible( false );
00396 }
00397 
00398 void DefaultProgress::slotMounting( KIO::Job*, const QString & dev, const QString & point )
00399 {
00400   setCaption(i18n("Mounting %1").arg(dev));
00401   sourceEdit->setText(point);
00402   setDestVisible( false );
00403 }
00404 
00405 void DefaultProgress::slotUnmounting( KIO::Job*, const QString & point )
00406 {
00407   setCaption(i18n("Unmounting"));
00408   sourceEdit->setText(point);
00409   setDestVisible( false );
00410 }
00411 
00412 void DefaultProgress::slotCanResume( KIO::Job*, KIO::filesize_t resume )
00413 {
00414   if ( resume ) {
00415     resumeLabel->setText( i18n("Resuming from %1").arg(KIO::number(resume)) );
00416   } else {
00417     resumeLabel->setText( i18n("Not resumable") );
00418   }
00419 }
00420 
00421 void DefaultProgress::setDestVisible( bool visible )
00422 {
00423   // We can't hide the destInvite/destEdit labels,
00424   // because it screws up the QGridLayout.
00425   if (visible)
00426   {
00427       destInvite->show();
00428       destEdit->show();
00429 
00430     destInvite->setText( i18n("Destination:") );
00431   }
00432   else
00433   {
00434       destInvite->hide();
00435       destEdit->hide();
00436     destInvite->setText( QString::null );
00437     destEdit->setText( QString::null );
00438   }
00439 }
00440 
00441 void DefaultProgress::slotClean() {
00442   if (d->keepOpenChecked) {
00443     mode = Done;
00444     slotPercent(0, 100);
00445     d->cancelClose->setGuiItem( KStdGuiItem::close() );
00446     d->openFile->setEnabled(true);
00447     slotProcessedSize(0, m_iTotalSize);
00448     d->keepOpen->setEnabled(false);
00449     if (!d->startTime.isNull()) {
00450       int s = d->startTime.elapsed();
00451       if (!s)
00452         s = 1;
00453       speedLabel->setText(i18n("%1/s (done)").arg(KIO::convertSize(1000 * m_iTotalSize / s)));
00454     }
00455     setOnlyClean(false);
00456   }
00457   else
00458     hide();
00459 }
00460 
00461 void DefaultProgress::slotKeepOpenToggled(bool keepopen)
00462 {
00463   d->keepOpenChecked=keepopen;
00464 }
00465 
00466 void DefaultProgress::checkDestination(const KURL& dest) {
00467   bool ok = true;
00468   if ( dest.isLocalFile() ) {
00469       QString path = dest.path( -1 );
00470       QStringList tmpDirs = KGlobal::dirs()->resourceDirs( "tmp" );
00471       for ( QStringList::Iterator it = tmpDirs.begin() ; ok && it != tmpDirs.end() ; ++it )
00472           if ( path.contains( *it ) )
00473               ok = false; // it's in the tmp resource
00474   }
00475 
00476   if ( ok ) {
00477     d->openFile->show();
00478     d->openLocation->show();
00479     d->keepOpen->show();
00480     d->location=dest;
00481   }
00482 }
00483 
00484 void DefaultProgress::slotOpenFile()
00485 {
00486   KProcess proc;
00487   proc << "konqueror" << d->location.prettyURL();
00488   proc.start(KProcess::DontCare);
00489 }
00490 
00491 void DefaultProgress::slotOpenLocation()
00492 {
00493   KProcess proc;
00494   d->location.setFileName("");
00495   proc << "konqueror" << d->location.prettyURL();
00496   proc.start(KProcess::DontCare);
00497 }
00498 
00499 void DefaultProgress::virtual_hook( int id, void* data )
00500 { ProgressBase::virtual_hook( id, data ); }
00501 
00502 } /* namespace */
00503 
00504 #include "defaultprogress.moc"
KDE Logo
This file is part of the documentation for kio Library Version 3.4.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Fri Apr 22 16:03:43 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003