00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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 #include <kwin.h>
00038
00039 #include "jobclasses.h"
00040 #include "defaultprogress.h"
00041
00042 namespace KIO {
00043
00044 class DefaultProgress::DefaultProgressPrivate
00045 {
00046 public:
00047 bool keepOpenChecked;
00048 bool noCaptionYet;
00049 KPushButton *cancelClose;
00050 KPushButton *openFile;
00051 KPushButton *openLocation;
00052 QCheckBox *keepOpen;
00053 KURL location;
00054 QTime startTime;
00055 };
00056
00057 DefaultProgress::DefaultProgress( bool showNow )
00058 : ProgressBase( 0 ),
00059 m_iTotalSize(0), m_iTotalFiles(0), m_iTotalDirs(0),
00060 m_iProcessedSize(0), m_iProcessedDirs(0), m_iProcessedFiles(0)
00061 {
00062 init();
00063
00064 if ( showNow ) {
00065 show();
00066 }
00067 }
00068
00069 DefaultProgress::DefaultProgress( QWidget* parent, const char* )
00070 : ProgressBase( parent ),
00071 m_iTotalSize(0), m_iTotalFiles(0), m_iTotalDirs(0),
00072 m_iProcessedSize(0), m_iProcessedDirs(0), m_iProcessedFiles(0)
00073 {
00074 init();
00075 }
00076
00077 void DefaultProgress::init()
00078 {
00079 d = new DefaultProgressPrivate;
00080
00081 #ifdef Q_WS_X11 //FIXME(E): Remove once all the KWin::foo calls have been ported to QWS
00082
00083 KWin::setIcons( winId(),
00084 KGlobal::iconLoader()->loadIcon( "filesave", KIcon::NoGroup, 32 ),
00085 KGlobal::iconLoader()->loadIcon( "filesave", KIcon::NoGroup, 16 ) );
00086 #endif
00087
00088 QVBoxLayout *topLayout = new QVBoxLayout( this, KDialog::marginHint(),
00089 KDialog::spacingHint() );
00090 topLayout->addStrut( 360 );
00091
00092 QGridLayout *grid = new QGridLayout( 2, 3 );
00093 topLayout->addLayout(grid);
00094 grid->addColSpacing(1, KDialog::spacingHint());
00095
00096 grid->addWidget(new QLabel(i18n("Source:"), this), 0, 0);
00097
00098 sourceEdit = new KLineEdit(this);
00099 sourceEdit->setReadOnly (true);
00100 grid->addWidget(sourceEdit, 0, 2);
00101
00102 destInvite = new QLabel(i18n("Destination:"), this);
00103 grid->addWidget(destInvite, 1, 0);
00104
00105 destEdit = new KLineEdit(this);
00106 destEdit->setReadOnly (true);
00107 grid->addWidget(destEdit, 1, 2);
00108
00109 m_pProgressBar = new KProgress(this);
00110 topLayout->addWidget( m_pProgressBar );
00111
00112
00113 QHBoxLayout *hBox = new QHBoxLayout();
00114 topLayout->addLayout(hBox);
00115
00116 sizeLabel = new QLabel(this);
00117 hBox->addWidget(sizeLabel);
00118
00119 resumeLabel = new QLabel(this);
00120 hBox->addWidget(resumeLabel);
00121
00122 progressLabel = new QLabel( this );
00123
00124
00125 progressLabel->setAlignment( QLabel::AlignRight );
00126 hBox->addWidget( progressLabel );
00127
00128 hBox = new QHBoxLayout();
00129 topLayout->addLayout(hBox);
00130
00131 speedLabel = new QLabel(this);
00132 hBox->addWidget(speedLabel, 1);
00133
00134 QFrame *line = new QFrame( this );
00135 line->setFrameShape( QFrame::HLine );
00136 line->setFrameShadow( QFrame::Sunken );
00137 topLayout->addWidget( line );
00138
00139 d->keepOpen = new QCheckBox( i18n("&Keep this window open after transfer is complete"), this);
00140 connect( d->keepOpen, SIGNAL( toggled(bool) ), SLOT( slotKeepOpenToggled(bool) ) );
00141 topLayout->addWidget(d->keepOpen);
00142 d->keepOpen->hide();
00143
00144 hBox = new QHBoxLayout();
00145 topLayout->addLayout(hBox);
00146
00147 d->openFile = new KPushButton( i18n("Open &File"), this );
00148 connect( d->openFile, SIGNAL( clicked() ), SLOT( slotOpenFile() ) );
00149 hBox->addWidget( d->openFile );
00150 d->openFile->setEnabled(false);
00151 d->openFile->hide();
00152
00153 d->openLocation = new KPushButton( i18n("Open &Destination"), this );
00154 connect( d->openLocation, SIGNAL( clicked() ), SLOT( slotOpenLocation() ) );
00155 hBox->addWidget( d->openLocation );
00156 d->openLocation->hide();
00157
00158 hBox->addStretch(1);
00159
00160 d->cancelClose = new KPushButton( KStdGuiItem::cancel(), this );
00161 connect( d->cancelClose, SIGNAL( clicked() ), SLOT( slotStop() ) );
00162 hBox->addWidget( d->cancelClose );
00163
00164 resize( sizeHint() );
00165 setMaximumHeight(sizeHint().height());
00166
00167 d->keepOpenChecked = false;
00168 d->noCaptionYet = true;
00169 setCaption(i18n("Progress Dialog"));
00170 }
00171
00172 DefaultProgress::~DefaultProgress()
00173 {
00174 delete d;
00175 }
00176
00177 void DefaultProgress::slotTotalSize( KIO::Job*, KIO::filesize_t bytes )
00178 {
00179 m_iTotalSize = bytes;
00180 if (d->startTime.isNull())
00181 d->startTime.start();
00182 }
00183
00184
00185 void DefaultProgress::slotTotalFiles( KIO::Job*, unsigned long files )
00186 {
00187 m_iTotalFiles = files;
00188 showTotals();
00189 }
00190
00191
00192 void DefaultProgress::slotTotalDirs( KIO::Job*, unsigned long dirs )
00193 {
00194 m_iTotalDirs = dirs;
00195 showTotals();
00196 }
00197
00198 void DefaultProgress::showTotals()
00199 {
00200
00201
00202
00203 if ( m_iProcessedFiles == 0 && m_iProcessedDirs == 0 )
00204 {
00205 QString tmps;
00206 if ( m_iTotalDirs > 1 )
00207
00208 tmps = i18n("%n folder", "%n folders", m_iTotalDirs) + " ";
00209 tmps += i18n("%n file", "%n files", m_iTotalFiles);
00210 progressLabel->setText( tmps );
00211 }
00212 }
00213
00214 void DefaultProgress::slotPercent( KIO::Job*, unsigned long percent )
00215 {
00216 QString tmp(i18n( "%1% of %2 ").arg( percent ).arg( KIO::convertSize(m_iTotalSize)));
00217 m_pProgressBar->setValue( percent );
00218 switch(mode) {
00219 case Copy:
00220 tmp.append(i18n(" (Copying)"));
00221 break;
00222 case Move:
00223 tmp.append(i18n(" (Moving)"));
00224 break;
00225 case Delete:
00226 tmp.append(i18n(" (Deleting)"));
00227 break;
00228 case Create:
00229 tmp.append(i18n(" (Creating)"));
00230 break;
00231 }
00232
00233 setCaption( tmp );
00234 d->noCaptionYet = false;
00235 }
00236
00237
00238 void DefaultProgress::slotInfoMessage( KIO::Job*, const QString & msg )
00239 {
00240 speedLabel->setText( msg );
00241 speedLabel->setAlignment( speedLabel->alignment() & ~Qt::WordBreak );
00242 }
00243
00244
00245 void DefaultProgress::slotProcessedSize( KIO::Job*, KIO::filesize_t bytes ) {
00246 m_iProcessedSize = bytes;
00247
00248 QString tmp;
00249 tmp = i18n( "%1 of %2 complete").arg( KIO::convertSize(bytes) ).arg( KIO::convertSize(m_iTotalSize));
00250 sizeLabel->setText( tmp );
00251 }
00252
00253
00254 void DefaultProgress::slotProcessedDirs( KIO::Job*, unsigned long dirs )
00255 {
00256 m_iProcessedDirs = dirs;
00257
00258 QString tmps;
00259 tmps = i18n("%1 / %n folder", "%1 / %n folders", m_iTotalDirs).arg( m_iProcessedDirs );
00260 tmps += " ";
00261 tmps += i18n("%1 / %n file", "%1 / %n files", m_iTotalFiles).arg( m_iProcessedFiles );
00262 progressLabel->setText( tmps );
00263 }
00264
00265
00266 void DefaultProgress::slotProcessedFiles( KIO::Job*, unsigned long files )
00267 {
00268 m_iProcessedFiles = files;
00269
00270 QString tmps;
00271 if ( m_iTotalDirs > 1 ) {
00272 tmps = i18n("%1 / %n folder", "%1 / %n folders", m_iTotalDirs).arg( m_iProcessedDirs );
00273 tmps += " ";
00274 }
00275 tmps += i18n("%1 / %n file", "%1 / %n files", m_iTotalFiles).arg( m_iProcessedFiles );
00276 progressLabel->setText( tmps );
00277 }
00278
00279
00280 void DefaultProgress::slotSpeed( KIO::Job*, unsigned long bytes_per_second )
00281 {
00282 if ( bytes_per_second == 0 ) {
00283 speedLabel->setText( i18n( "Stalled") );
00284 } else {
00285 QTime remaining = KIO::calculateRemaining( m_iTotalSize, m_iProcessedSize, bytes_per_second );
00286 speedLabel->setText( i18n( "%1/s ( %2 remaining )").arg( KIO::convertSize( bytes_per_second )).arg( remaining.toString() ) );
00287 }
00288 }
00289
00290
00291 void DefaultProgress::slotCopying( KIO::Job*, const KURL& from, const KURL& to )
00292 {
00293 if ( d->noCaptionYet ) {
00294 setCaption(i18n("Copy File(s) Progress"));
00295 d->noCaptionYet = false;
00296 }
00297 mode = Copy;
00298 sourceEdit->setSqueezedText(from.prettyURL());
00299 sourceEdit->home (false);
00300 setDestVisible( true );
00301 checkDestination( to );
00302 destEdit->setSqueezedText(to.prettyURL());
00303 destEdit->home (false);
00304 }
00305
00306
00307 void DefaultProgress::slotMoving( KIO::Job*, const KURL& from, const KURL& to )
00308 {
00309 if ( d->noCaptionYet ) {
00310 setCaption(i18n("Move File(s) Progress"));
00311 d->noCaptionYet = false;
00312 }
00313 mode = Move;
00314 sourceEdit->setSqueezedText(from.prettyURL());
00315 sourceEdit->home (false);
00316 setDestVisible( true );
00317 checkDestination( to );
00318 destEdit->setSqueezedText(to.prettyURL());
00319 destEdit->home (false);
00320 }
00321
00322
00323 void DefaultProgress::slotCreatingDir( KIO::Job*, const KURL& dir )
00324 {
00325 if ( d->noCaptionYet ) {
00326 setCaption(i18n("Creating Folder"));
00327 d->noCaptionYet = false;
00328 }
00329 mode = Create;
00330 sourceEdit->setSqueezedText(dir.prettyURL());
00331 sourceEdit->home (false);
00332 setDestVisible( false );
00333 }
00334
00335
00336 void DefaultProgress::slotDeleting( KIO::Job*, const KURL& url )
00337 {
00338 if ( d->noCaptionYet ) {
00339 setCaption(i18n("Delete File(s) Progress"));
00340 d->noCaptionYet = false;
00341 }
00342 mode = Delete;
00343 sourceEdit->setSqueezedText(url.prettyURL());
00344 sourceEdit->home (false);
00345 setDestVisible( false );
00346 }
00347
00348 void DefaultProgress::slotTransferring( KIO::Job*, const KURL& url )
00349 {
00350 if ( d->noCaptionYet ) {
00351 setCaption(i18n("Loading Progress"));
00352 d->noCaptionYet = false;
00353 }
00354 sourceEdit->setSqueezedText(url.prettyURL());
00355 sourceEdit->home (false);
00356 setDestVisible( false );
00357 }
00358
00359 void DefaultProgress::slotStating( KIO::Job*, const KURL& url )
00360 {
00361 setCaption(i18n("Examining File Progress"));
00362 sourceEdit->setSqueezedText(url.prettyURL());
00363 sourceEdit->home (false);
00364 setDestVisible( false );
00365 }
00366
00367 void DefaultProgress::slotMounting( KIO::Job*, const QString & dev, const QString & point )
00368 {
00369 setCaption(i18n("Mounting %1").arg(dev));
00370 sourceEdit->setSqueezedText(point);
00371 sourceEdit->home (false);
00372 setDestVisible( false );
00373 }
00374
00375 void DefaultProgress::slotUnmounting( KIO::Job*, const QString & point )
00376 {
00377 setCaption(i18n("Unmounting"));
00378 sourceEdit->setSqueezedText(point);
00379 sourceEdit->home (false);
00380 setDestVisible( false );
00381 }
00382
00383 void DefaultProgress::slotCanResume( KIO::Job*, KIO::filesize_t resume )
00384 {
00385 if ( resume ) {
00386 resumeLabel->setText( i18n("Resuming from %1").arg(KIO::number(resume)) );
00387 } else {
00388 resumeLabel->setText( i18n("Not resumable") );
00389 }
00390 }
00391
00392 void DefaultProgress::setDestVisible( bool visible )
00393 {
00394
00395
00396 if (visible)
00397 {
00398 destInvite->show();
00399 destEdit->show();
00400
00401 destInvite->setText( i18n("Destination:") );
00402 }
00403 else
00404 {
00405 destInvite->hide();
00406 destEdit->hide();
00407 destInvite->setText( QString::null );
00408 destEdit->setText( QString::null );
00409 }
00410 }
00411
00412 void DefaultProgress::slotClean() {
00413 if (d->keepOpenChecked) {
00414 slotPercent(0, 100);
00415 d->cancelClose->setText( KStdGuiItem::close().text() );
00416 d->openFile->setEnabled(true);
00417 slotProcessedSize(0, m_iTotalSize);
00418 d->keepOpen->setEnabled(false);
00419 if (!d->startTime.isNull()) {
00420 int s = d->startTime.elapsed();
00421 if (!s)
00422 s = 1;
00423 speedLabel->setText(i18n("%1/s (done)").arg(KIO::convertSize(1000 * m_iTotalSize / s)));
00424 }
00425 setOnlyClean(false);
00426 }
00427 else
00428 hide();
00429 }
00430
00431 void DefaultProgress::slotKeepOpenToggled(bool keepopen)
00432 {
00433 d->keepOpenChecked=keepopen;
00434 }
00435
00436 void DefaultProgress::checkDestination(const KURL& dest) {
00437 bool ok = true;
00438 if ( dest.isLocalFile() ) {
00439 QString path = dest.path( -1 );
00440 QStringList tmpDirs = KGlobal::dirs()->resourceDirs( "tmp" );
00441 for ( QStringList::Iterator it = tmpDirs.begin() ; ok && it != tmpDirs.end() ; ++it )
00442 if ( path.contains( *it ) )
00443 ok = false;
00444 }
00445
00446 if ( ok ) {
00447 d->openFile->show();
00448 d->openLocation->show();
00449 d->keepOpen->show();
00450 d->location=dest;
00451 }
00452 }
00453
00454 void DefaultProgress::slotOpenFile()
00455 {
00456 KProcess proc;
00457 proc << "konqueror" << d->location.prettyURL();
00458 proc.start(KProcess::DontCare);
00459 }
00460
00461 void DefaultProgress::slotOpenLocation()
00462 {
00463 KProcess proc;
00464 d->location.setFileName("");
00465 proc << "konqueror" << d->location.prettyURL();
00466 proc.start(KProcess::DontCare);
00467 }
00468
00469 void DefaultProgress::virtual_hook( int id, void* data )
00470 { ProgressBase::virtual_hook( id, data ); }
00471
00472 }
00473
00474 #include "defaultprogress.moc"