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
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* )
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
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 );
00099
00100 QGridLayout *grid = new QGridLayout( 2, 3 );
00101 topLayout->addLayout(grid);
00102 grid->addColSpacing(1, KDialog::spacingHint());
00103
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
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
00134
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"));
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
00217
00218
00219 if ( m_iProcessedFiles == 0 && m_iProcessedDirs == 0 )
00220 {
00221 QString tmps;
00222 if ( m_iTotalDirs > 1 )
00223
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
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
00424
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;
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 }
00503
00504 #include "defaultprogress.moc"